Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OO design principles and patterns


Published on

Principles and patterns of object oriented design. answering the most common questions faced when designing a system, e.g., how to model the domain? how to prepare the code for modification? how to handle an object's life cycle?

Published in: Software

OO design principles and patterns

  1. 1. Object Oriented Design is mainly about behaviour, not structure. 2
  2. 2. What to ask when designing 0 Which class should a responsibility be assigned to? 0 How to organize the system’s responsibilities? 0 How to model the domain? 0 How to handle an object’s lifecycle? 0 How to prepare the code for modification? 3
  3. 3. Which class should a responsibility be assigned to? 4
  4. 4. 0Information Expert [GRASP] 0 A responsibility dealing with X should be assigned to the object holding X 0Single Responsibility Principle [SOLID] 0 Each class should have one and only one responsibility 0Interface Segregation [SOLID] 0 Favour small specific interfaces so clients don’t depend on interfaces they don’t use 5
  5. 5. Corollary of Information Expert Getters and setters are Evil (don’t ask for data, delegate as much as possible) 6
  6. 6. Procedural thinking 7
  7. 7. Object thinking 8
  8. 8. How to organize the system’s responsibilities? 9
  9. 9. Layers pattern 0 You are designing a system whose dominant characteristic is a mix of low- and high-level issues, where high-level operations rely on the lower-level ones. 0 Therefore 0 Structure your system into an appropriate number of layers and place them on top of each other, each providing a specific level of abstraction. 10 GoF
  10. 10. Common architecture Source: domain driven design , Eric Evans 11
  11. 11. 0Low coupling [GRASP] 0 Keep coupling of elements to a minimum. Avoid circular dependencies. 0High Cohesion [GRASP] 0 Keep related elements close together 0Indirection [GRASP] 0 Avoid tight coupling by creating an indirection layer 13
  12. 12. Façade 0 Work is actually performed by a series of subsystem but this level of complexity must be hidden from the client 0 Therefore 0 Create a facade object offering a simpler, high level interface which delegates work in the actual subsystems 14 GoF
  13. 13. Controller 0 You need to coordinate application activity - the interactions of a use case with the UI or external systems 0 Therefore 0 Assign the responsibility of use case coordination to a dedicated use case controller which exposes a business API (application layer) and performs no business logic but delegates to the right domain objects instead 15 GRASP
  14. 14. How to model the domain? 16
  15. 15. Look at your domain model’s ubiquitous language 17
  16. 16. Entity 0 Some objects in the domain have a thread of continuity which we need to track by its identity. 0 Therefore 0 Model objects in the real world as entities, assigning each object one or more identities. Equality of references is done comparing the identity of the object. 18 DDD
  17. 17. Entity: example Class Account{ public Account(AccountNumber accn) {…} public boolean equals(Object other) { if (other==this) return true; if (!(other instanceof Account)) return false; return (this.getID() == (Account)other.getID()); } public void withdraw(Money amount) { if (hasEnoughBalance(amount) || overdraftAllowed(amount)) { // business logic for withdrawing // and updating balances } } } 19
  18. 18. Value Object 0 Not everything needs an identity; some things matter for the value of its attributes. 0 Therefore 0 Create immutable objects whose equality is determined by the equality of its attributes. 20 DDD
  19. 19. Value object: example Class Balance{ public Balance(Money amount, Calendar asOf) {…} // getters (but no setters) public Money amount() {…} public Calendar asOf() {…} // creates a new Balance object // keeping this and the other object unchanged public Balance add(Money some) {…} public Balance add(Money some, Calendar effectiveOn) {…} public Balance subtract(Money some) {…} ... public boolean equals(Object other) {…} } 21
  20. 20. Service 0 Some business operations are not naturally placed in a certain domain object 0 Therefore 0 Create a service object that handles only that operation and coordinates the necessary domain objects. 23 DDD
  21. 21. Service: example class TransferService { public void transfer(Money amount, Account from, Account to) { if (isAllowedToTransfer(from, amount, to) { from.withdraw(amount); to.deposit(amount); } } private boolean isAllowedToTransfer(Account from, Money amount, Account to) { // rules specific to account transfers // (e.g., maximum allowed amount to transfer for // international account) } } 24
  22. 22. An Example 25 N-to-M relationships are hard
  23. 23. A pragmatic design 26 • Remove unnecessary associations • Force traversal direction of bidirectional associations • Reduce cardinality by qualification of the association we are still left with a tangle of interconnected objects...
  24. 24. Aggregate 0 Some objects are closely related together and we need to control the scope of data changes so that invariants are enforced 0 Therefore 0 Keep related objects with frequent changes bundled in an aggregate 0 control access to the “inner” objects thru one single “root” object 27 DDD
  25. 25. A more pragmatic design 28 Legend: • Account aggregate • Customer aggregate Address is a value object so it can be freely shared among several aggregates
  26. 26. How to handle an object’s lifecycle? 29
  27. 27. Object’s lifecycle 1. An object is created 2. The object is used 3. It must be persisted for later use 4. Later, the object is reconstructed from persistence 5. It is used (provably changed) 6. It is stored back again for later use 7. … 30
  28. 28. Separate use from construction 31
  29. 29. Factories 0 Creating a (large) object might be a complex task and/or the client must be decoupled from the actual type of the created object. 0 Therefore 0 Place construction logic in a dedicated factory which encapsulates object creation for all clients. 32 DDD
  30. 30. 0 Creator [GRASP] 0 Assign class A creation responsibility to the class which either (1) contains A’s instances; or (2) holds the data for initializing an A’s instance 0 Factory Method [GoF] 0 A class method that simplifies the creation of different implementations of the same interface 0 Simple Factory [GoF] 0 A class made up of only factory methods 0 Abstract Factory [GoF] 0 Handles the creation of related or dependent product families 33
  31. 31. Repository 0 Client code needs to obtain a reference to an object in order to use it (sometimes, the desired object needs to be reconstructed from persistence). After using it the client wants the object to be persisted again. 0 Therefore 0 Encapsulate the logic needed for obtaining object references in a Repository. The repository handles all the persistence logic and abstracts the client code from such details. 34 DDD
  32. 32. 35 Repositoryexample
  33. 33. Repositories and layers 36
  34. 34. How to prepare the code for modification? 37
  35. 35. Protected Variation 0 You need to design objects, components or systems so that variations in those elements don’t impact other elements 0 Therefore 0 Identify points of predicted variation and create a stable interface around them. 38 GRASP
  36. 36. 0Open/Close Principle [SOLID] 0 A class should be open for extension and adaption and closed for modification 0Dependency Inversion Principle [SOLID] 0 Clients should depend on abstractions, not concretions. I.e., program to an interface not a realization. 39
  37. 37. 0Polymorphism [GRASP] 0 When behaviour varies depending on type 0Template Method [GoF] 0 Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. 0Liskov Substitution Principle [SOLID] 0 Any method expecting A should work properly with any object derived from A 40
  38. 38. Liskov Substitution Principle’s Corollary Derived classes should adhere strictly to the semantics of the contract see also, Design by Contract: Pre-conditions Post-conditions Invariants 41
  39. 39. Strategy 0 Sometimes there is a business policy (expressed in the domain) that must be enforced but it actually may have different variations of concrete policies 0 Therefore 0 Define a common interface for the policy and provide different implementations decoupling the client from the actual policy and allowing for permutation and independent evolution. 42 GoF
  40. 40. Topic Principles and patterns Which class should a responsibility be assigned to? Information Expert Single Responsibility Principle Interface Segregation Principle How to organize the system’s responsibilities? Layers Façade Controller How to model the domain? Entity Value Object Service Aggregate How to handle an object’s lifecycle? Factories Repositories How to prepare the code for modification? Protected Variation Open/Close Principle Dependency Inversion Principle Liskov Substitution Principle Template Method Strategy 44
  41. 41. References 0 Domain Driven Design. Eric Evans 0 Why getters and setters are Evil. Allan Holub. java/why-getter-and-setter-methods-are-evil.html 0 Design Principles and Design Patterns. Robert Martin. les_and_Patterns.pdf 0 Design Patterns-Elements of Reusable Object-oriented Software, Gamma et al. (Gang of Four) 0 Applying UML and Patterns; Craig Larman; (2nd ed.); 2002. 45