object design
DESCRIPTION
TRANSCRIPT
![Page 1: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/1.jpg)
OBJECT DESIGNDhaval Dalal
software-artisan.comPart I: OO Design Guidelines
![Page 2: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/2.jpg)
DESIGN SMELLS
Tell-tale signs of poor architectureSource: Robert C. Martin
![Page 3: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/3.jpg)
3
DESIGN SMELLS
Rigidity (Difficult to Change)
Every change causes too many changes in other parts of the system.
Fragility (Easily Breakable)
A change affects unexpected parts of the system and causes it to break.
Needless Repetition (Duplication)
Same code appears over and over again in different forms.
![Page 4: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/4.jpg)
4
DESIGN SMELLS
Immobility (Cannot Disentangle)
It is hard to reuse in another application because it cannot be disentangled from the current application.
Opacity (Difficulty in Understanding)
Tendency of a module to be difficult to understand.
Needless Complexity (Over Engineering)
Results from speculative approach (gold-plating!).
Use YAGNI
![Page 5: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/5.jpg)
5
DESIGN SMELLS
Viscosity (Toughness in preserving design)
High Design Viscosity
Design preserving methods are harder to employ than hacks.
Easy to do the wrong thing, but hard to do the right thing.
Environment Viscosity
![Page 6: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/6.jpg)
OO DESIGN GUIDELINESStrong Commitment to Encapsulation
Strong Commitment to Loose Coupling Law of Demeter
Single Responsibility PrincipleCoding to Super-Types & LSP
Encapsulate Variations & apply OCPCreate Role-Based Behaviors
Dependency InversionFavor Composition over Inheritance
Dependency InjectionDependency Elimination
![Page 7: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/7.jpg)
STRONG COMMITMENT TO ENCAPSULATION
Ask (or query) an Object to get something for you.
if (customer.getAge() == 60) { // do something}
// Still Query, but encapsulatedif (customer.isSenior()) {
// do something
}
Tell (or command) an Object to do something for you.
customer.loyaltyPoints()
![Page 8: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/8.jpg)
TELL, DON’T ASK!
Procedural code gets information, inspects that information and then makes decisions.
Object-oriented code tells objects to do things.
Declare or State (think declaratively) what you want and do not process (not procedurally) what you want.
![Page 9: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/9.jpg)
PRESERVE ENCAPSULATION
Getters and Setters generally break encapsulation.
Don’t introduce getters or setters for all fields of an object...just because IDEs provide this facility
Don’t introduce getters just because tests need it.
engine.start();
assertThat(engine.isRunning(), is(true));
![Page 10: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/10.jpg)
PRESERVE ENCAPSULATION
Don’t introduce getters just because tests need it.
engine.start();
assertThat(engine.isRunning(), is(true));
Use Observable Behavior instead, this improves the API
assertThat(engine.start(), is(true));
![Page 11: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/11.jpg)
PRESERVE ENCAPSULATION
Avoid returning a private collection
public class Building {
private List<Floor> floors = new ArrayList<Floor>();
//...
public List<Integer> getFloors() { return floors; }
}
Instead return a copy or a read-only version of it.
public class Building {
private List<Floor> floors = new ArrayList<Floor>();
//...
public List<Integer> getFloors() {
return Collections.unmodifiableList(floors);
}
}
![Page 12: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/12.jpg)
STRONG COMMITMENT TO LOOSE COUPLING
A E
D
C
B
dog.getBody().getTail().wag()
dog.expressHappiness()
dog.getBody().getTail().setLength(50)
state altering“train wrecks”
“train wrecks”refactored
dog.getBody().getTail().getLength()state querying“train wrecks”
![Page 13: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/13.jpg)
LAW OF DEMETER
No “Train Wrecks”
Send messages only to object’s immediate neighbors.
Principle of least knowledge
Don’t talk to more objects than required.
The more objects you talk to, more the risk of getting broken when any one of the object changes.
Restrict class interaction in order to minimize coupling among classes.
![Page 14: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/14.jpg)
CONFORMING TO LAW OF DEMETER
A method of an Object should invoke only the methods of the following kinds of objects
itself
its parameters
any objects it creates or directly collaborates
any composite object
As a guidance-rule, more than two “dots” means the Law of Demeter is being violated.
![Page 15: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/15.jpg)
15
SINGLE RESPONSIBILITY PRINCIPLE (SRP)
There should never be more than one reason to change a class.
A responsibility is an axis of change.
Key is in identifying which is an axis of change and which is not?
Many responsibilities means many reasons to change.
This is hard to see, as we think
responsibility in groups.
![Page 16: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/16.jpg)
16
BENEFITS OF SRP…
Removes the “Immobility Smell” from Design
Immobility is the inability to reuse software from other projects or from parts of the same project.
Deodorizes the “Rigidity Smell”
Generates a highly cohesive design.
![Page 17: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/17.jpg)
17
CODING TO WHAT?
Coding to an super-type
Shape s = new Circle();
s.draw();
Coding to an implementation
Circle c = new Circle();
c.draw();
Code to Super-type, not to Sub-Types
![Page 18: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/18.jpg)
18
LISKOV’S SUBSTITUTION PRINCIPLE (LSP)
Sub-types must be substitutable for their Base-types
Be able to operate upon derivatives of that base class without knowing it.
It makes clear that in OO Design “IS-A” relationship is about behavioral semantics; semantics that clients depend on.
Not intrinsic private behavior, but extrinsic public behavior.
![Page 19: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/19.jpg)
19
HANDLING CHANGES
When a single change to a program
Results in a cascade of changes to dependent modules.
The program becomes rigid, unpredictable and not reusable.
This is sign of
a bad design
![Page 20: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/20.jpg)
20
ENCAPSULATE VARIATIONS
Identify things that vary and separate them from the concepts that stay the same.
Evolve an Abstraction representing the concept.
Introduce Interface or Abstract super-type.
Unify variations on this pivot of abstraction.
Encapsulate each variation using a Concrete Class that implements/extends the above super-type.
![Page 21: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/21.jpg)
21
APPLY OPEN/CLOSED PRINCIPLE
It says that you should design modules that never change.
When requirements change, extend the behavior of modules
By adding new code.
Not by changing old code that already works.
![Page 22: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/22.jpg)
22
OPEN/CLOSED PRINCIPLE (OCP)
Software Entities (Classes, Modules, Methods, etc…)
Should be
Open for Extension
but
Closed for Modification.
![Page 23: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/23.jpg)
OPEN FOR EXTENSIONBehavior of the module can be extended.
Make the module behave in new and different ways as the requirements of the application change.
The source code of such a module is inviolate.
Resist making source code changes to it.
CLOSED FOR MODIFICATION
![Page 24: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/24.jpg)
HOW CAN THESE TWO OPPOSING
ATTRIBUTES BE RESOLVED?
Abstraction is the Key.
![Page 25: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/25.jpg)
25
WHAT MAKES A GOOD ABSTRACTION?
An Abstraction focuses
On client’s perspective and suppresses implementation perspective.
A simple logical model that can be described in a sentence or a two.
It does not mean class’s processing is simple!
It simply means that the class is focused on a small set of activities.
Source: S/W Design Studio, by Dr. Jim Fawcett, Syracuse University
![Page 26: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/26.jpg)
CREATE ROLES-BASED BEHAVIORS
Name a role around a metaphor or around the concepts which you are abstracting out.
This helps a client understand and relate to an object’s behavior.
Role should convey everything about the implemented behavior.
![Page 27: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/27.jpg)
27
OCP IN REALITY
100% closure is not attainable.
Closure must be strategic.
We design systems such that they are closed to the most likely kinds of changes that we foresee.
![Page 28: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/28.jpg)
28
DEPENDENCY STRUCTURE: PROCEDURAL DESIGN
Source: Robert C. Martin
![Page 29: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/29.jpg)
29
DEPENDENCY INVERSION PRINCIPLE (DIP)
High level modules should not depend on low level modules.
Both should depend upon abstractions.
Abstractions should not depend upon specifics.
Specifics should depend upon abstractions.
![Page 30: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/30.jpg)
30
DEPENDENCY STRUCTURE: OO DESIGN
Source: Robert C. Martin
Dependencies
are inverted
![Page 31: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/31.jpg)
31
EXTENDING OBJECT CAPABILITIES
Composition promotes “dynamic reuse”
Is a weaker association
Vary object behavior dynamically by changing collaborators
Inheritance promotes “static reuse”
Is a stronger association
Vary object behavior at compile time.
“has-a” can be better than “is-a”, leads to supple design
![Page 32: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/32.jpg)
SUB-TYPE PROLIFERATION
Evils of Inheritance
Deep hierarchies obscure understanding.
As a guidance, avoid creating hierarchies that are more than 2 levels deep.
Contractual changes on super-type ripple through Wide hierarchies.
Interfaces or Abstract Classes provide flexibility at the cost of themselves being rigid.
In general, Favor Composition over Inheritance
![Page 33: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/33.jpg)
33
INTERFACE SEGREGATION PRINCIPLE (ISP)
Deals with avoiding “Fat”, Non-cohesive class interfaces.
Groups of methods used by different clients.
Don’t force clients to depend on methods they don’t use.
Else they are subject to changes to those methods.
Results in an inadvertent coupling between all the clients.
![Page 34: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/34.jpg)
34
ABSTRACTION PROLIFERATION
Make these
code blocks
Too many abstractions make it hard to understand the system.
![Page 35: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/35.jpg)
LOOK MA....NO COUPLING!
Too many abstractions make it hard to understand the system.
Refactor to Closures/Lambdas wherever its sensible and possible
Dependency Elimination
You don’t need abstract classes or interfaces to achieve polymorphism.
Close your class against modifications.
![Page 36: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/36.jpg)
YET ANOTHER GUIDELINE
Dependency Elimination can be better than Dependency Inversion.
Requires Language Level support to achieve this
As of now, Java6 does not support closures.
Groovy, Ruby, C# make this possible to achieve.
![Page 37: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/37.jpg)
37
OBJECT DESIGN GUIDELINES SUMMARY
Design for preserving Encapsulation
Tell, Don’t Ask!
Extend Object Capabilities
By favoring Composition over Inheritance
Design for High Cohesion and Reuse
SRP, ISP
![Page 38: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/38.jpg)
38
OBJECT DESIGN GUIDELINES SUMMARY
Design for Reduced Coupling
Law of Demeter, OCP, LSP.
Separate Policy from Mechanism (DIP)
Design for No Coupling
Dependency Elimination
![Page 39: Object design](https://reader038.vdocuments.site/reader038/viewer/2022102804/54923871b479590d408b4753/html5/thumbnails/39.jpg)
39
OBJECT DESIGN GUIDELINES SUMMARY
Uphold Good Housekeeping Policy.
Use and clean your own stuff…
Uphold Green Environment Policy.
Undo changes made by you to your environment.