Re: Classes as units of reuse
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Sun, 06 Nov 2005 15:57:01 GMT
Responding to Borah...
A component in this sense will be defined by an interface which may have as members other components - this provides for a flat structural view of a system (which is what Lahman would probably like going by his emphasis on components and sub systems).
As for behavior, components are implemented by classes. A class would implement only one component at the most. In cases where a component is a composition of components, the class implementing the component would reuse the behavior of all member components unless the component (the class implements) explicitly over rides a member component's method.
So, Component ABC { method abc( ); method pqr( ); Component DEF; Component XYZ; }
where, Component ABC is a composition of components DEF and XYZ.
Component DEF { pqr( ); Component MNO; } where, ABC's implementation of method pqr( ) will over ride DEF's implementation of pqr( ) in a class AAA that implements ABC.
I have a problem with pqr() as you describe it. Object properties in a Class Model should be normalized and that includes behaviors. IOW, the same behavior should not be a responsibility of two different classes (e.g., ABC and DEF). However, that requires some qualification. If you treat the outer class as a GoF Facade pattern, then it is really just a smart interface for the contained objects and it just re-dispatches to the <single> object that actually owns the behavior.
[Similarly, abstract methods in superclasses are a form of simple dispatch. However, this can be coupled with inclusion polymorphism to provide an elegant way to substitute behavior based on context. But it is best to only provide the implementations at the leaf level or, at least, to avoid overriding them.]
So if ABC.pqr() simply redispatches to DEF.pqr(), one really isn't violating the normalization because only DEF.pqr() provides the behavior.
The thing that is not clear in your pseudo code is the nature of the relationship between ABC and DEF. Does "component DEF;" indicate a relationship implementation by embedding DEF in ABC's implementation? A relationship implementation through a reference to a DEF object that can be instantiated separately from ABC? Or are you just trying to define an inheritance tree where ABC inherits DEF?
IMO, the second approach would be the best where one abstracts some set of objects (e.g., DEF and XYZ) with the proper functionality and then decouples their details from the rest of the application via a Facade interface (ABC) to which the clients all talk. If necessary the Facade class can encapsulate dispatching rules that depend on context. (Though such rules are complicated, it probably suggests that there is a problem with the basic object abstractions.)
The first and second approaches are basically just implementation of a classic functional decomposition tree using objects. That tends to be a nightmare for maintainability because of the hierarchical dependencies. That will be manifested in the first case by a gazillion variants of ABC that cobble together things in slightly different ways and code bloat. It will be manifested the second case by shotgun refactorings whenever the tree itself needs to be modified to accommodate new variants in functionality.
Note that the hierarchical structure is already manifested in your nesting of "components". In the OO paradigm one basically has three levels of logical indivisibility: subsystem, object, and responsibility. Within a subsystem one should strive to make objects peers and allow them to communicate on a peer-to-peer basis. So one really shouldn't need Facade-like composition except in special circumstances. (OTOH, Facades are ideally suited to subsystem interfaces because one wants to hide the details.) One uses the level of abstraction of subsystems and the limited context of subsystem subject matter to reduce the complexity of a subsystem's implementation so that this is possible.
[The apparent need for a Facade within subsystems often arises because the level of abstraction of the subsystem is not consistent. That is, the objects encapsulated by the Facade are actually providing low level services compared to the objects outside the Facade. One uses the Facade so that the other objects don't have to know about the details. But that just says that the details are at a significantly lower level of abstraction and should be in a lower level subsystem.]
************* There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@xxxxxxxxxxxxxxxxx Pathfinder Solutions -- Put MDA to Work http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman (888)OOA-PATH
.
- References:
- Classes as units of reuse
- From: Kallol Borah
- Re: Classes as units of reuse
- From: H. S. Lahman
- Re: Classes as units of reuse
- From: Kallol Borah
- Classes as units of reuse
- Prev by Date: Re: 4 Object implementation types ?
- Next by Date: Re: Is a ConfigParser/ObjCreator a Builder?
- Previous by thread: Re: Classes as units of reuse
- Next by thread: Re: Classes as units of reuse
- Index(es):
Relevant Pages
|