User Tools

Site Tools


principles:encapsulate_the_concept_that_varies

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
principles:encapsulate_the_concept_that_varies [2013-01-30 10:44]
christian OCP, SRP
principles:encapsulate_the_concept_that_varies [2019-10-07 08:29] (current)
2600:1700:6470:22d0:c500:a3eb:d473:80ab [Contrary Principles]
Line 5: Line 5:
 ===== Context ===== ===== Context =====
 /* fill in contexts here: */ /* fill in contexts here: */
-  * [[contexts:​Object-Oriented Design]]  +  * [[contexts:​Object-Oriented Design]] 
 +  * [[contexts:​API Design]] 
 +  * [[contexts:​Architecture]]
  
 ===== Principle Statement ===== ===== Principle Statement =====
Line 14: Line 15:
  
 ===== Description ===== ===== Description =====
 +
 +This principle has two aspects that roughly correspond to the two sub-principles [[Single Responsibility Principle|SRP]] and [[Open-Closed Principle|OCP]]. The first one is about making changes local. Everything which is supposed to change in the future should be encapsulated in a single module. This means [[glossary:​cross-cutting concerns]] are avoided as much as possible. This is not completely possible but in many cases it is.
 +
 +The second aspect is about introducing abstractions. Sometime the varying concept is one which varies at runtime rather than by maintenance. So at runtime it is decided upon a certain variation or there can be even several variations at the same time. In this case there has to be an abstract base class or an interface which encapsulates the varying concept. Several concrete descendant classes then specify the concrete variation.
 +
 +The difference between the two aspects is whether the varying concept is one that changes over time during maintenance or one that may change at runtime. Nevertheless the advice is the same: encapsulate the concept that varies.
  
  
 ===== Rationale ===== ===== Rationale =====
 +
 +There are two reasons for this principle. The first reason is locality. When a varying concept is properly encapsulated in a single module, only this module is affected in case of a change. This reduces maintenance effort and [[glossary:​ripple effects]].
 +
 +The second reason comes to play when the varying concept is implemented as an abstract class or interface. In this case a variation can be introduced without changing existing and tested code. This reduces testing effort (as already tested code does not need to be retested as it is not changed) as well as ripple effects (as the enhancement is done simply by adding a class. Note that for this rationale to work, the [[Liskov Substitution Principle]] also has to be adhered to.
  
  
 ===== Strategies ===== ===== Strategies =====
 +
 +  * Introduce a separate module for the concept that may change in the future. In that way the future change will only affect that particular module. If the varying concept is properly encapsulated,​ only this module will have to change.
 +  * Introduce an interface encapsulating the varying concept. The interface may be implemented differently by several classes and code that only relies on the interface can handle any class implementing the interface. In case of another variation, just another class has to be introduced and this class has to implement the interface. If the abstraction is done properly, no module has to change.
 +  * Introduce an abstract base class encapsulating the varying concept. This is basically the same as introducing an interface. But here, implementation can also be inherited. So common parts can remain in the abstract base class whereas only the actual variations are defined in the subclasses. By means of method overriding, the implementation of the base class methods can be changed without touching the base class directly.
 +  * Use design patterns. Several design patterns use the above techniques to encapsulate varying concepts. For example:
 +    * Abstract Factory: A family of objects changes.
 +    * Factory Method: The exact type of an object to create changes.
 +    * Adapter: The interface of a module changes.
 +    * Bridge: A concept varies in more than one aspect.
 +    * Decorator: The behavior of certain methods may need to be enhanced.
 +    * Iterator: The traversal algorithm of a structure changes. Or the structure itself changes resulting in the need for a different traversal algorithm.
 +    * Observer: The objects interested in a certain event may change.
 +    * State: The behavior in a certain state or the state machine (states and transitions) of a certain module changes.
 +    * Strategy: An algorithm changes.
 +    * Template Method: The concrete steps in an algorithms change.
 +    * Visitor: New operations have to be added to a given more or less static inheritance structure of classes.
 +    * ...
 +
 +===== Caveats =====
 +
 +See section [[#contrary principles]].
  
  
 ===== Origin ===== ===== Origin =====
 +
 +The principle is stated, explained and used in the GoF book:
 +
 +Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: //​[[wp>​Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]]//​ ("GoF book"​),​ p. 29
 +
 +But the idea if ECV is actually much older. It was first presented in
 +
 +David Parnas: //​[[http://​citeseerx.ist.psu.edu/​viewdoc/​summary?​doi=10.1.1.132.7232|On the Criteria To Be Used in Decomposing Systems into Modules]]//
  
  
 ===== Evidence ===== ===== Evidence =====
 /* Comment out what is not applicable and explain the rest: */ /* Comment out what is not applicable and explain the rest: */
-/* +/*  * [[wiki:​Proposed]] ​*/ 
-  * [[wiki:​Proposed]] + 
-  * [[wiki:Examined]] +  * [[wiki:Accepted]]: This principle was popularly described in the GoF book and can thus be regarded accepted. 
-  * [[wiki:Accepted]] +  * [[wiki:Examined]]: Many of the patterns in the GoF book are precisely about encapsulating varying concepts. See strategies section. 
-  * [[wiki:​Questioned]] + 
-*/+/*  * [[wiki:​Questioned]]*/​
  
 ===== Relations to Other Principles ===== ===== Relations to Other Principles =====
  
 ==== Generalizations ==== ==== Generalizations ====
- 
-  * [[Generalization Principle]] 
- 
  
 ==== Specializations ==== ==== Specializations ====
Line 48: Line 85:
 ==== Contrary Principles ==== ==== Contrary Principles ====
  
-  * [[More Is More Complex]] (MIMC): ECV demands adding a new class for a new varying concept. +  ​* **[[More Is More Complex]] (MIMC)**: ECV demands adding a new class for a new varying concept. 
-  ​[[Keep It Simple Stupid]] (KISS): ECV demands adding a new class for a new varying concept. This adds complexity+  * [[Model Principle]] (MP): ECV sometimes results in classes which do not correspond ​to a real-world concept in the sense of MP. A "​concept that varies"​ can also be a technical concept.
-  * [[Model Principle]] (MP): ECV sometimes results in classes which do not correspond ​top a real-world concept in the sense of MP. A "​concept that varies"​ can also be a technical concept.+
  
 ==== Complementary Principles ==== ==== Complementary Principles ====
  
-  * [[Dependency Inversion ​Principle]] (DIP): ECV may result in the creation ​of abstract ​classes (i.e. the concepts) and descendant concrete classes ​(i.ethe variations). DIP now tells that other classes should only depend on the abstractions+  * [[Low Coupling]] (LC): ECV results in the creation of a new module. When introducing such a new module, LC has to be adhered to. 
- +  * [[Liskov Substitution ​Principle]] (LSP): ECV may result in the introduction ​of an abstract ​base classHere it is important to get the abstraction right. Otherwise LSP may be violated. 
 +  * [[Generalization Principle]] ​(GP): Encapsulating a varying concept typically results in a more generally applicable solutionThis is especially true when an abstract concept is encapsulated by introducing an interface or an abstract class. 
 +  * [[Dependency Inversion Principle]] (DIP): ECV may result in the introduction of an abstract base classHere DIP demands ​that other classes should only depend ​on this new abstract base class and not on the concrete subclasses
 +  * [[Information Hiding/​Encapsulation]] (IH/E): ECV tells that varying concepts should be encapsulated. IH/E then tells how encapsulation is done.
 ==== Principle Collections ==== ==== Principle Collections ====
  
 {{page>​collections:​OOD Principle Language#​Box}} {{page>​collections:​OOD Principle Language#​Box}}
-{{page>​collections:​SOLID#​Box}} 
-{{page>​collections:​Principles in "​Object-Oriented Software Construction"#​Box}} 
  
-===== Example ​=====+ 
 +===== Examples ​=====
  
  
 ===== Description Status ===== ===== Description Status =====
 /* Choose one of the following and comment out the rest: */ /* Choose one of the following and comment out the rest: */
-[[wiki:​Stub]] +/*[[wiki:​Stub]]*
-/*[[wiki:​Incomplete]]*/+[[wiki:​Incomplete]]
 /​*[[wiki:​Complete]]*/​ /​*[[wiki:​Complete]]*/​
  
Line 75: Line 112:
  
   * Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides: //​[[wp>​Design Patterns|Design Patterns:   * Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides: //​[[wp>​Design Patterns|Design Patterns:
- ​Elements of Reusable Object-Oriented Software]]//​, p. 29 + ​Elements of Reusable Object-Oriented Software]]//​ 
-  * Bertrand Meyer: //[[wp>​Object-Oriented Software Construction]]//, p. 57pp. +  * [[Single Responsibility Principle]] 
-  * Robert C. Martin: //Agile Software Development,​ Principles, Patterns, ​and Practices//,​ p. 99pp. +  * [[Open-Closed Principle]] 
-  * [[http://​www.butunclebob.com/​ArticleS.UncleBob.PrinciplesOfOod|ButUncleBob:​ Principles of OOD]]+ 
 +===== Discussion ===== 
 + 
 +Discuss this wiki article ​and the principle on the corresponding ​[[talk:principles:​Encapsulate the Concept that Varies|talk page]].
principles/encapsulate_the_concept_that_varies.1359539076.txt.gz · Last modified: 2013-05-20 12:46 (external edit)