Object Oriented Design: Difference between revisions
Line 68: | Line 68: | ||
== Package Dependency == |
== Package Dependency == |
||
[[Image: |
[[Image:A-depends-b.png]] |
||
A depends on B. |
A depends on B. |
||
Latest revision as of 21:13, 14 September 2021
Reference
http://ifacethoughts.net/2006/03/24/design-principles/
Encapsulation
- hides implementation
- enforces modularity
Polymorphism
- many forms
- Java - overridden methods
Open Closed Principle (OCP)
- Open for extension - closed for modification
Ability to add new features without modifying existing classes <- e.g. define new subclass Principle: reduce coupling to abstract level
Polymorphic open closed principle
- interface stays the same - implementation may change
- abstract interface
- any implementation may be substituted
equivalent to LSP
Liskov Substitution Principle (LSP)
Let q(x) be a property about object x of type T q(y) should be true for objects y of type S where S is a subtype of T
i.e. objects of type T may be replaced by objects of type S for all S where S is a subtype of T
closely related to design by contract
- preconditions can not be strengthened
- post conditions can not be weakened
The above conditions have meaning out side of the Java language and can be hard to track/enforce
Design by contract
- mutual obligations and benefits
- Obligations on entry - preconditions
- Guarentee of property on exit - postconditions
- Maintain property ( assumed on entry, guarantee on exit) class invariant
Violations of LSP => Violation of OCP Violation of OCP does not imply LSP violation
Dependency Inversion Principle
Coupling should be at the abstract (interface or abstract class) level not at the concrete class level DIP is the means to achieve OCP
Interface segregation Principle
- Specific interfaces are better than general interfaces
- Avoid multiple roles
- Single role is more cohesive
Composite Reuse Principle
- Favour polymorphic composition over inheritance
- Avoid overriding default behaviour - behaviour should be the same for all ISAs
Principle of least knowledge
Only talk to your immediate friends
Any object should know as little as possible about software or properties of anything else - sub components included
i.e. object A may call methods on object B but should not call methods on objects contained within B
- Advantage: easier to maintain - more adaptable
- Disadvantage: class may become bloated with wrapper methods ([Facade Pattern])
- Alternative solution is a get method returning interface not concrete class (of aggregate/composite class) - common in Java API
Package Dependency
If the contents of B change then this may impact package A
Release Reuse Equivalence Principle
Use of the class in the package => must deploy package Unit of reuse is unit of release
- Don't copy code from one class to another - fixes to original will be reused
- You should not need access to source code just deploy library
- The package granularity helps reduce burdensome effort of tracking every class dependency
Common Closure Principle
Classes that change together belong together
- Functional cohesion - grouping parts of a module together that perform well defined task - e.g. XML
- Class cohesion - Functionally sound & don't cross responsibilities boundries
Common Reuse Principle
- Classes that aren't reused together shouldn't be grouped together
- Consider likelihood of classes changing together when choosing packaging
- Avoid unwanted dependencies
Acyclic Dependency Principle
- Dependencies between packages should not form a cycle
- Dependencies should only form a DAG Directed Acyclic Graph
- Factor out the cyclic forming part into a new Class => positive re-use
Important for a deployment perspective
Stable Dependencies Principles
Packages likely to experience frequent change (less stable) should have fewer incoming dependencies - Can have many outgoing dependencies
Packages less likely to change may have more incoming dependencies - Fewer outgoing dependencies
Stable Abstraction Principle
Stable packages should be more abstract packages
More stable packages should contain a higher number of abstract classes or interfaces
- should heavily depend on them
Less stable packages contain high number of concrete classes
- should not depend on such packages