The purpose of the patterns in this group is to divide a software system into several parts in such a way that individual parts can be built, changed, replaced, and reused independently. The advantage of decoupling is local change, i.e., the system can be changed by modifying one or only a few parts, instead of changing everything.
In comparison to the following category on integration, the emphasis in these patterns is on how to split a system into components, not on combining them.
The patterns in this category differ greatly in their range of applicability. The patterns Module, Abstract Data Type, and Hierarchical Layers, for example, have an extremely broad applicability, whereas Iterator, Proxy, Facet, or Visitor apply in much narrower design situations.
Flexibility: change/replace implementation, hardware, I/O, OS, memory resources, etc. without affecting clients.
Implementation: make interface independent of likely changes (information hiding).
Note: Modules are supported by Java interfaces, Modula modules, Ada packages, or even .h,.c, and .o files in C. Normally, it is not possible to instantiate a module more than once (there is no progr. language construct for doing this). Instead, compiling and linking a module instantiates it.
Flexibility: change/replace implementation, hardware, I/O, OS, memory resources, etc. without affecting clients.
Implementation: make interface independent of likely changes (information hiding).
Note: the intent of ADT is similar to that of module, but an ADT is typically smaller (single data type). It is also possible to create multiple instances of an ADT. For a module, there is normally only one instance and a module may combine several related ADTs.
Examples of ADTs:
Flexibility: clients are independent of each other; add/remove clients; change implementation of data structure.
Implementation: get/set or query/update methods; synchronization for parallel access (e.g., transaction).
See also: Blackboard
Flexibility: change/replace/reuse manager.
Implementation: use Singleton for the manager component.
Flexibility: vary internal structure of aggregate/container; multiple iterators may operate simultaneously on the same object.
Implementation: separate iterator state from aggregate/container; standardized interface for iteration.
Flexibility: extension/contraction(partial reuse)/replacement; incremental build and test.
Implementation: uses-relation among layers must be acyclic.
Examples:
Flexibility: abstraction and implementation evolve independently; can add new abstraction or implementation without affecting the other.
Implementation: separate layers for abstraction and implementation, fixed interface of implementation.
Flexibility: change/replace "hidden" subsystems including interface.
Implementation: facade calls hidden subsystem interfaces.
Flexibility: add/withdraw functionality without affecting original object or clients, without subclassing.
Implementation: proxy has same interface as original; delegate request to original before/after adding functionality.
Flexibility: extend interface, extend functionality
Implementation: An object registers its extensions and returns them if queried.
Flexibility: add new subclasses where permitted, without changing application logic in framework.
Implementation: uses subclassing, template methods, factory methods, builders, abstract factories.
Flexibility: a) decouple operations that exist in variants for many classes from those classes; b)extensibility: add new operations.
Implementation: common accept interface in classes; methods for all classes in visitor.
Variations:
|
![]() |
![]() |