Applying the ReuseRelease Equivalence Principle (REP)


Applying the Reuse/Release Equivalence Principle (REP)

What portions of the payroll application can we reuse? Another division of our company wanting to reuse our payroll system but having a different set of policies could not reuse Classifications, Methods, Schedules, or Affiliations but could reuse PayrollDomain, PayrollApplication, Application, PayrollDatabase, and, possibly, PDImplementation. On the other hand, another department wanting to write software that analyzed the current employee database could reuse PayrollDomain, Classifications, Methods, Schedules, Affiliations, PayrollDatabase, and PDImplementation. In each case, the granule of reuse is a component.

Seldom, if ever, would only a single class from a component be reused. The reason is simple: The classes within a component should be cohesive. That is, that they depend on one another and cannot be easily or sensibly separated. It would make no sense, for example, to use the Employee class without using the PaymentMethod class. In fact, in order to do so, you would have to modify the Employee class so that it did not contain a PaymentMethod instance. Certainly, we don't want to support the kind of reuse that forces us to modify the reused components. Therefore, the granule of reuse is the component. This gives us another cohesion criterion to use when trying to group classes into components: The classes should not only be closed together but also reusable together in conformance with REP.

Consider again our original component diagram in Figure 30-1. The components that we might like to reuse, such as transactions or PayrollDatabase, are not easily reusable, because they drag along a lot of extra baggage. The PayrollApplication component depends on everything. If we wanted to create a new payroll application that used a different set of schedule, method, affiliation, and classification policies, we would not be able to use this package as a whole. Instead, we would have to take individual classes from PayrollApplication, transactions, Methods, Schedules, Classifications, and Affiliations. By disassembling the components in this way, we destroy their release structure. We cannot say that release 3.2 of PayrollApplication is reusable.

Since Figure 30-1 violates CRP, the reuser, having accepted the reusable fragments of our various components, will not be able to depend on our release structure. By reusing the PaymentMethod class, the reuser is affected by a new release of Methods. Most of the time, the changes will be to classes not being reused, yet the reuser must still track our new release number and probably recompile and retest the code.

This will be so difficult to manage that the reuser's most likely strategy will be to make a copy of the reusable components and evolve that copy separately from ours. This is not reuse. The two pieces of code will become different and will require independent support, effectively doubling the support burden.

These problems are not exhibited by the structure in Figure 30-2. The components in that structure are easier to reuse. PayrollDomain does not drag along much baggage. It is reusable independently of any of the derivatives of PaymentMethod, PaymentClassification, PaymentSchedule, and so on.

The astute reader will notice that the component diagram in Figure 30-2 does not completely conform to CRP. Specifically, the classes within PayrollDomain do not form the smallest reusable unit. The transaction class does not need to be reused with the rest of the component. We could design many applications that access the Employee and its fields but never use a transaction.

This suggests a change to the component diagram, as shown in Figure 30-3. This separates the transactions from the elements they manipulate. For example, the classes in the MethodTransactions component manipulate the classes in the Methods component.

Figure 30-3. Updated payroll component diagram


We have moved the TRansaction class into a new component, named transactionApplication, which also contains transactionSource and a class named transactionApplication. These three form a reusable unit. The PayrollApplication class has now become the grand unifier. It contains the main program and also a derivative of transactionApplication, called PayrollApplication, which ties the TextParserTransactionSource to the TRansactionApplication.

These manipulations have added yet another layer of abstraction to the design. The TRansactionApplication component can now be reused by any application that obtains TRansactions from a transactionSource and then Executes them. The PayrollApplication component is no longer reusable, since it is extremely dependent. However, the transactionApplication component has taken its place and is more general. Now, we can reuse the PayrollDomain component without any TRansactions.

This certainly improves the reusability and maintainability of the project, but the cost is five extra components and a more complex dependency architecture. The value of the trade-off depends on the type of reuse that we might expect and the rate at which we expect the application to evolve. If the application remains stable and few clients reuse it, perhaps this change is overkill. On the other hand, if many applications will reuse this structure or if we expect the application to experience many changes, perhaps the new structure would be superior; it's a judgment call, and it should be driven by data rather a speculation. It is best to start simple and grow the component structure as necessary. Component structures can always be made more elaborate, if necessary.




Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net