Object Oriented Design Sudarsun S.,  M.Tech Director – R & D Checktronix India Pvt Ltd Chennai 600010
Objectives To explain how a software design may be represented as a set of interacting objects that manage their own state and operations To introduce various models that describe an object-oriented design To introduce design patterns
What is an OBJECT An  instance  of a CLASS Contains meaningful data  Concepts that occupy memory space at runtime are, according to the definition, objects  If not, they are CLASSES For example: data type vs. double
A little Quiz… #1 Class or Object? Dog is a generalization of Scooby-Doo Dog Scooby-Doo
A little Quiz (cont’d)… #2 Class or Object? The concept of  subclass ! Dog is a subclass of the Animal class Animal is a generalization of Dog Dog Scooby-Doo Animal
A little Quiz (cont’d)… #3 Class or Object? The concept of  polymorphism ! Animal Dog Bird
Characteristics of OOD Objects are abstractions of real-world or system entities and manage themselves Objects are independent and encapsulate state and representation information.  System functionality is expressed in terms of object services Shared data areas are eliminated Objects communicate by message passing Objects may be distributed Objects may execute sequentially or in parallel
Interacting objects
Advantages of OOD Easier maintenance. Objects may be  understood as stand-alone entities Objects are appropriate reusable components For some systems, there may be an obvious mapping from real world entities to system objects
Object-oriented development Object-oriented analysis, design and programming are related but distinct OOA is concerned with developing an object model of the application domain OOD is concerned with developing an object-oriented system model to implement requirements OOP is concerned with realising an OOD using an OO programming language such as Java or C++
Objects and object classes  Objects are entities in a software system which represent instances of real-world and system entities Object classes are templates for objects Classes may be used to create objects Object classes may inherit attributes and services from other object classes
Object communication Conceptually, objects communicate by message passing Messages The name of the service requested by the calling object. Copies of the information required to execute the service  and the name of a holder for the result of the service. In practice, messages are often implemented  by procedure (a.k.a. method) calls Name = method name Information = parameter list Result holder = method return value
Message examples // Call a method associated with a buffer  // object that returns the next value  // in the buffer v = circularBuffer.Get() ; // Call the method associated with a // thermostat object that sets the  // temperature to be maintained thermostat.setTemp(20) ;
Generalisation and inheritance Objects are members of classes which define attribute types and operations Classes may be arranged in a class hierarchy where one class (a super-class) is a generalisation of one or more other classes (sub-classes) A sub-class inherits the attributes and operations from its super class and may add new methods or attributes of its own It is a reuse mechanism at both the design and the programming level  Inheritance introduces complexity and this is undesirable, especially in critical systems
A generalisation hierarchy
Object Relationships Objects and object classes participate in relationships with other objects and object classes In UML, such a relationship is indicated by an association Associations may be annotated with information that describes the association
Object identification Identifying objects (or object classes) is the most difficult part of object oriented design There is no “magic formula” for object identification It relies on the skill, experience  and domain knowledge of system designers Object identification is an iterative process You are unlikely to get it right first time
Approaches to identification Use a grammatical approach based on a natural language description of the system (used in HOOD method) Base the identification on tangible things in the application domain Use a behavioural approach and identify objects based on what participates in what behaviour Use a scenario-based analysis – the objects, attributes and methods in each scenario are identified
Object interface specification Object interfaces have to be specified so that the objects and other components can be designed in parallel Designers should avoid designing the interface representation but should hide this in the object itself Objects may have several interfaces which are viewpoints on the methods provided
Examples of design models Sub-system models that show logical groupings of objects into coherent subsystems UML package diagrams Sequence models that show the sequence of object interactions UML sequence diagrams State machine models that show how individual objects change their state in response to events UML statechart diagrams Other models include use-case models, aggregation models, generalisation models,etc.
Weather station subsystems
Weather station - data collection sequence
State charts Object states State transitions triggered by requests to objects
OO Design Process –  Access Layer Create Mirror classes:   For every business class identified and created, create one access class.  Simplify classes and their relationships – to eliminate redundant classes and structures Redundant classes:   Do not keep 2 classes that perform similar request and results translation activities.  Select one and eliminate the other. Methods:   Revisit the classes that consist of only one or two methods to see if they can be eliminated or combined with existing classes.
Object Oriented Design Process Design the view layer classes Design the macro & micro level user interface, identifying view layer objects Test usability and user satisfaction From the UML class diagram, begin to extrapolate the  classes to build  and  classes to reuse.   Also think about the inheritance structure.  If we have several classes that seem related but have specific differences, probably it means an inheritance structure. All designed components must trace back to the user requirements.
Example: Invoice
Example: Invoice Classes that come to mind:  Invoice ,  LineItem , and  Customer   Good idea to keep a list of candidate classes  Brainstorm, simply put all ideas for classes onto the list  You can cross not useful ones later
Finding Classes Keep the following points in mind:  Class represents set of objects with the same behavior  Entities with multiple occurrences in problem description are good candidates for objects  Find out what they have in common  Design classes to capture commonalities  Represent some entities as objects, others as primitive types  Should we make a class Address or use a String?  Not all classes can be discovered in analysis phase  Some classes may already exist
CRC Card CRC Card Describes a class, its responsibilities, and its collaborators  Use an index card for each class  Pick the class that should be responsible for each method (verb)  Write the responsibility onto the class card  Indicate what other classes are needed to fulfill responsibility (collaborators)
CRC Card
Self Check Suppose the invoice is to be saved to a file. Name a likely collaborator.  Looking at the invoice, what is a likely responsibility of the  Customer  class?  What do you do if a CRC card has ten responsibilities?
Answers FileWriter   To produce the shipping address of the   customer.  Reword the responsibilities so that they are at a higher level, or come up with more classes to handle the responsibilities.
Relationships Between Classes Inheritance  Aggregation  Dependency
Inheritance Is-a  relationship  Relationship between a more general class (superclass) and a more specialized class (subclass)  Every savings account is a bank account  Continued…
Inheritance Every circle is an ellipse (with equal width and height)  It is sometimes abused  Should the class  Tire  be a subclass of a class  Circle ?  The  has-a  relationship would be more appropriate
Aggregation Has-a  relationship  Objects of one class contain references to objects of another class  Use an instance variable  A tire has a circle as its boundary:  Every car has a tire (in fact, it has four)  class Tire {   . . .   private String rating;   private Circle boundary; }
Example class Car extends Vehicle {   . . .   private Tire[] tires; }
Example UML Notation for Inheritance and Aggregation
Dependency Uses  relationship  Example: many of our applications depend on the Scanner class to read input  Aggregation is a stronger form of dependency  Use aggregation to remember another object between method calls
UML Relationship Symbols Open Dotted  Dependency Diamond Solid Aggregation Triangle Dotted Interface Implementation Triangle Solid Inheritance Arrow Tip Line Style Symbol Relationship
Self Check Consider the  Bank  and  BankAccount  classes. How are they related?  Consider the  BankAccount  and  SavingsAccount  objects. How are they related?  Consider the  BankAccountTester  class. Which classes does it depend on?
Answers Through aggregation. The bank manages bank account objects.  Through inheritance.  The  BankAccount ,  System , and  PrintStream  classes.
Attributes and Methods in UML Attributes and Methods in a Class Diagram
Multiplicities any number (zero or more): *  one or more: 1..*  zero or one: 0..1  exactly one: 1  An Aggregation Relationship with Multiplicities
Aggregation and Association Association: more general relationship between classes  Use early in the design phase  A class is associated with another if you can navigate from objects of one class to objects of the other  Given a  Bank  object, you can navigate to  Customer  objects  Continued…
Aggregation and Association An Association Relationship
Five-Part Development Process Gather requirements  Use CRC cards to find classes, responsibilities, and collaborators  Use UML diagrams to record class relationships  Use  javadoc  to document method behavior  Implement your program
Printing an Invoice – Requirements Task: print out an invoice  Invoice: describes the charges for a set of products in certain quantities  Omit complexities  Dates, taxes, and invoice and customer numbers  Print invoice  Billing address, all line items, amount due  Line item  Description, unit price, quantity ordered, total price  For simplicity, do not provide a user interface  Test program: adds line items to the invoice and then prints it Continued…
Sample Invoice
CRC Cards Discover classes  Nouns are possible classes  Invoice Address LineItem Product Description Price Quantity Total Amount Due
CRC Cards Analyze classes Invoice Address LineItem  // Records the product and the quantity Product Description // Field of the Product class Price  // Field of the Product class Quantity  // Not an attribute of a Product Total  // Computed–not stored anywhere Amount Due  // Computed–not stored anywhere  Continued…
CRC Cards Classes after a process of elimination Invoice Address LineItem Product
CRC Cards for Printing Invoice Invoice  and  Address  must be able to format themselves:
CRC Cards for Printing Invoice Add collaborators to invoice card:
CRC Cards for Printing Invoice Product  and  LineItem  CRC cards:
CRC Cards for Printing Invoice Invoice  must be populated with products   and quantities:
Printing an Invoice – UML Diagrams The Relationships Between the Invoice Classes
Method Documentation Use  javadoc  documentation to record the behavior of the classes  Leave the body of the methods blank  Run  javadoc  to obtain formatted version of documentation in HTML format  Advantages:  Share HTML documentation with other team members  Format is immediately useful: Java source files  Supply the comments of the key methods
Method Documentation –  Invoice  class  /**   Describes an invoice for a set of purchased products. */ public class Invoice {   /**   Adds a charge for a product to this invoice.   @param aProduct the product that the customer ordered   @param quantity the quantity of the product   */   public void add(Product aProduct, int quantity)   {   }   /**   Formats the invoice.   @return the formatted invoice   */   public String format()   {   } }
Method Documentation –  LineItem  class  /**   Describes a quantity of an article to purchase and its price. */ public class LineItem {   /**   Computes the total cost of this line item.   @return the total price   */   public double getTotalPrice()   {   }   /**   Formats this item.   @return a formatted string of this line item   */   public String format()   {   } }
Method Documentation –  Product  class  /**   Describes a product with a description and a price. */ public class Product {   /**   Gets the product description.   @return the description   */   public String getDescription()   {   }   /**   Gets the product price.   @return the unit price   */   public double getPrice()   {   } }
Method Documentation –  Address  class  /**   Describes a mailing address. */ public class Address {   /**   Formats the address.   @return the address as a string with three lines   */   public String format()   {   } }
Implementation Invoice  aggregates  Address  and    LineItem   Every invoice has one billing address  An invoice can have many line items: public class Invoice {   . . .   private Address billingAddress;   private ArrayList<LineItem> items; }
Implementation A line item needs to store a Product object and quantity: public class LineItem {   . . .   private int quantity;   private Product theProduct; }
Implementation The methods themselves are now very easy  Example:  getTotalPrice  of  LineItem  gets the unit price of the product and multiplies it with the quantity /**   Computes the total cost of this line item.   @return the total price */ public double getTotalPrice() {   return theProduct.getPrice() * quantity; }
Self Check Which class is responsible for computing the amount due? What are its collaborators for this task?  Why do the format methods return  String  objects instead of directly printing to  System.out ?
Answers The  Invoice  class is responsible for computing the amount due. It collaborates with the  LineItem  class.  This design decision reduces coupling. It enables us to reuse the classes when we want to show the invoice in a dialog box or on a web page.
Suh’s Axioms of OOD The independence axiom:   Maintain independence of components. Each component must satisfy its requirements without affecting other requirements.  The information axiom:  Minimize the information content of the design.  It is concerned with simplicity.  Rely on Occam’s Razor
Occum’s Razor rule of simplicity The best designs usually involve  the least complex code  but not necessarily the fewest number of classes or methods.  Minimizing complexity  should be the goal, because that produces the most easily maintained and enhanced application.  In an object-oriented system, the best way to minimize complexity is  to use inheritance  and the system’s built-in classes and to add as little as possible to what already is there.
Some Corollaries… Uncoupled design Single purpose Large number of  simple classes Strong mapping Standardization Design with  inheritance
Uncoupled Design Coupling is a measure of the strength of association established by a connection from one object or software component to another. Types Interaction  coupling amount and complexity of messages between components. Preferred to be minimal What happens when high and low ? Inheritance  coupling coupling between super and sub classes coupling in terms of attributes and methods Preferred to be high What happens when high and low ? { override all, unused methods }
Cohesion Cohesion reflects the “single-purposeness” of an object.  Highly cohesion    Lower coupling Method cohesion:  method carrying one function.  A method that carries multiple functions is undesirable.  Class cohesion:  All the class’s methods and attributes are highly cohesive, meaning to be used by internal methods or derived classes’ methods.
Corollary 2:  Single Purpose  Every class should be clearly defined and necessary in the context of achieving the system’s goals.  When we document a class, we should be able to explain its purpose in a sentence or two.  If we cannot, then the class should be subdivided into independent pieces.  Each method must provide only one service. Each method should be of moderate size, no more than a page; half a page is better.
Achieving Multiple Inheritance What is Single inheritance? What is the problem with Multiple Inheritance ? What is the ideal case for MI ?  In C++ objects can inherit behavior from unrelated areas of the class tree.  How to determine which behavior to get from which class, particularly when several ancestors define the same method.  Virtual Inheritance !!??
Class Visibility Purpose of Access Specifiers ? Difference between c++ struct and class ? The class’s protocol or the messages that a class understands, can be hidden from other objects (private protocol) or made available to other objects (public protocol).  Public protocols define the functionality and external messages of an object.  Private protocols define the implementation of an object. The lack of well-designed protocol can manifest itself as encapsulation leakage.  It happens when details about a class’s internal implementation are disclosed through the interface
Design patterns A design pattern is a way of reusing abstract knowledge about a problem and its solution Patterns are devices that allow programs to share knowledge about their design A pattern is a description of the problem and the essence of its solution Documenting patterns is one way to reuse and share the information about how it is best to solve a specific design problem A pattern should be sufficiently abstract to be reused in different settings Patterns often rely on object characteristics such as inheritance and polymorphism
Pattern elements Name A meaningful pattern identifier Problem description Solution description Not a concrete design but a template for a design solution that can be instantiated in different ways Consequences The results and trade-offs of applying the pattern
Types of Patterns Creational Abstract Factory Structural Adapter Façade Proxy Behavioral Observer Mediator
Patterns by Example: Multiple displays enabled by Observer A=10% B=40% C=30% D=20% Application data A B C D A D C B Relative Percentages Y 10  40  30 20 X 15  35  35 15 Z 10  40  30 20 A  B  C  D Change notification Requests, modifications
The Observer pattern Name Observer Description Separates the display of object state from the object itself Problem description Used when multiple displays of state are needed Solution description See slide with UML description Consequences Optimisations to enhance display performance are impractical
The Observer pattern observerState= subject     getState(); Subject attach (Observer) detach (Observer) Notify () Observer Update() Concrete Observer Update() observerState Concrete Subject GetState() SetState() subjectState observers subject For all x in observers{ x     Update(); }
The Mediator Pattern Description Define an object that encapsulates how a set of objects interact Mediator promotes loose coupling by keeping objects from referring to each other explicitly It lets you vary their interaction independently Applicability Complex interaction exists You do not want to bury the interaction in the objects Distributed behavior should be customizable without a lot of sub classing  Consequences Limits sub classing Decouples colleagues Simplifies object protocols Abstracts how objects cooperate Centralizes control
The Mediator Pattern
The Façade Pattern Description Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Applicability Need to provide a simple interface to a complex system Need to decouple a subsystem from its clients Need to provide an interface to a software layer  Consequences Shields clients from subsystem components Promotes weak coupling between the subsystem and its clients
Facade   Pattern: Problem Subsystem classes Client Classes Need to communicate with
Facade   Pattern: Solution Subsystem classes Fac ade Client Classes
The Façade Pattern
The Proxy Pattern Description Provide a surrogate or placeholder for another object to control access to it. Applicability Remote proxies can hide the fact that a real object is in another address space Virtual proxies can create expensive objects on demand. Protection proxies can control access to an object. Smart references can perform additional action above a simple pointer
The Proxy Pattern
The Adapter Pattern Description Convert the interface of a class into another interface clients expect Adapter lets classes work together that could not otherwise because of incompatible interfaces Applicability Need to use an existing class whose interface does not match Need to make use of incompatible classes Consequences Class adapter commits to the concrete Adapter class Class adapter introduces only one object and no pointer indirection
The Adapter Pattern
The Abstract Factory Pattern Description Provides an interface for creating families of related or dependent objects without specifying their concrete classes. Applicability Need to abstract from details of implementation of products  Need to have multiple families of products  Need to enforce families of products that must be used together  Need to hide product implementations and just present interfaces  Consequences Isolates concrete classes  Makes exchanging product families easy  Promotes consistency among products  Supporting new kinds (in each family) of products is difficult
The Abstract Factory Pattern AbstractFactory CreateProductA() CreateProductB() ConcreteFactory1 Client ProductA1 ProductA2 AbstractProductA ProductB2 ProductB1 AbstractProductB ConcreteFactory2 CreateProductA() CreateProductB()
Abstract Factory Example WidgetFactory CreateScrollbar() CreateWindow() Window ScrollBar WWidgetFactory MacWidgetFactory Client WWindow MacWindow MacScrollBar WScrollBar One for each standard.
What is dependency management? What bearing does DM have on software? What is the result of poor DM? What is the advantage of good DM? Dependency Management
What is dependency management? A simple idea - as interdependencies increase, features like reusability, flexibility, and maintainability decrease. Dependency management is controlling interdependencies.
What bearing does DM have on software? Coupling and cohesion are the eternal concerns of software development One can say that OO is just a set of tools and techniques for Dependency Management
What is the penalty for practicing poor DM? It is rigid It is fragile It is not reusable It has high viscosity A system with poor dependency structure will typically exhibit these four negative traits:
It is Rigid The impact of a change cannot be predicted If not predicted, it cannot be estimated Time and cost cannot be quantified Managers become reluctant to authorize change Official Rigidity for “Roach Motel” modules Rigidity is the inability  to be changed
Changes with Rigidity The System Officially Rigid Area Where the change should be made Where the change must be made now Are we containing risk, or spreading rot?
It is Fragile A single change requires a cascade of subsequent changes New errors appear in areas that seem unconnected to the changed areas Quality is unpredictable. The development team loses credibility Software changes seem to exhibit non-local effects
Increasing Risk Defects v. Cumulative Modifications Systems tend to become increasingly fragile over time. Intentional, planned partial rewrites may be necessary to sustain growth and maintenance. Changes Probability of  introducing a bug 1.0
It is not reusable Desirable parts of the  design are dependent  upon undesirable parts The work and risk of  extracting the desirable  part may exceed the  cost of redeveloping  from scratch.
The Trailer The Trailer
It has high viscosity When the “right changes” are  much more difficult  than hacking, the viscosity of the system is high. Over time, it will become increasingly difficult to continue developing the product. Viscosity is resistance to fluid motion.
What is the benefit  of good DM? Interdependencies are managed, with firewalls separating aspects that need to vary independently. Fewer Trailers Slow the rot More Flexible Less fragile, the bugs are boxed in Easier to reuse Easier to make the right change
What causes “Code Rot”? A case study “The Copy Routine” It’s been blamed on stupidity, lack of discipline, and phases of the moon, but...
First Version All designs start well The program is an overnight success! How could it be more simple, elegant, and maintainable? void copy(void) { int ch; while( (ch=ReadKeyboard()) != EOF) WritePrinter(ch); }
Second Version We sometimes want to read from paper tape reader. We could put a parameter in the call, but we have hundreds of users already!  No big deal, this is just an exception… we can make it work. Oh, no! Nobody said the requirements might change!
Second Version Design bool GtapeReader = false; // remember to clear void copy(void) { int ch; while( (ch=GtapeReader ? ReadTape() : ReadKeyboard()) != EOF) WritePrinter(ch); }
Third Version How unexpected! Requirements changed again! bool GtapeReader = false;  Bool GtapePunch = false;  // remember to clear void copy(void) { int ch; while( (ch=GtapeReader ? ReadTape() : ReadKeyboard()) != EOF) GtapePunch ? WritePunch(ch) : WritePrinter(ch); } It seems that sometimes we need to write to a paper tape punch. We’ve had this problem before, and just added a flag. Looks like it should work again.
Example of a Good Design First and only version. void Copy() { int c; while( (c=getchar()) != EOF) putchar(c); } But wait! Aren’t we supposed to be learning OO design? This isn’t OO is it?
… is it? FILE is an abstraction It represents some kind of byte stream It has many variations It has methods Read, Write, getchar, putchar, etc The methods are *dynamically* bound It is a small program based on abstractions! FILE is a class, just implemented differently.
Rephrased in OO interface Reader { char read(); } interface Writer { void write(char c); } public class Copy { Copy(Reader r, Writer w) { itsReader = r; itsWriter = w; } public void copy() { int c; while( (c==itsReader.read()) != EOF ) itsWriter.write(c); } private Reader itsReader; private Writer  itsWriter; }
Class Design Principles S RP:  The Single Responsibility Principle O CP: The Open/Closed Principle L SP: The Liskov Substitution Principle I SP: The Interface Segregation Principle D IP: The Dependency Inversion Principle From: Agile Software Development: Principles, Patterns, and Practices. Robert C. Martin, Prentice Hall, 2002.
The Single Responsibility Principle A class should have one, and only one, reason to change.
Open/Closed Principle A principle which states that we should add new functionality by adding new code, not by editing old code. Defines a lot of the value of OO programming Abstraction is the key “ Modules should be open for extension, but closed for modification” -Bertrand Meyer
Abstraction is Key Client/Server relationships are “open” Changes to servers cause changes to clients Abstract servers “close” clients to changes in implementation. Abstraction is  the most important   word in OOD
The Shape Example Procedural (not closed) implementation OO (closed) implementation
Procedural (open) version enum ShapeType {circle, square}; struct Shape  {enum ShapeType itsType;}; struct Circle  { enum ShapeType itsType; double itsRadius; Point itsCenter; }; void DrawCircle(struct Circle*) struct Square  { enum ShapeType itsType; double itsSide; Point itsTopLeft; }; void DrawSquare(struct Square*) #include <Shape.h> #include <Circle.h> #include <Square.h> typedef struct Shape* ShapePtr; void  DrawAllShapes(ShapePtr list[], int n) { int i; for( i=0; i< n, i++ ) { ShapePtr s = list[i]; switch ( s->itsType ) { case square: DrawSquare((struct Square*)s); break; case circle: DrawCircle((struct Circle*)s); break; } } } Shape.h Circle.h Square.h DrawAllShapes.c
What is wrong with the code? DrawAllShapes is not closed. Switch/case  tend to recur in diverse places. If we add a shape, we add to the switch/case All  switch/case  statements must be found and editd. Switch/Case  statements are seldom this tidy When we add to the enum, we must rebuild everything The software is both rigid and brittle It can be demonstrated to work. Isn’t that the important thing?
A Closed Implementation Class Shape { public: virtual void Draw() const =0; }; #include <Shape.h> void  DrawAllShapes(Shape* list[],int n) { for(int i=0; i< n; i++) list[i]->draw(); } Shape.h DrawAllShapes.cpp Circle.h Square.h Class Square: public Shape { public: virtual void Draw() const; }; Class Circle: public Shape { public: virtual void Draw() const; };
Strategic Closure Closure Against What? Closure is strategic. You have to choose which changes you’ll isolate yourself against. What if we have to draw all circles first? Now DrawAllShapes must be edited (or we have to hack something) Opened Where? Somewhere, someone has to instantiate the individual shapes.  It’s best if we can keep the dependencies confined Use abstraction to gain explicit closure provide class methods which can be dynamically invoked to determine  general  policy decisions  e.g. draw Squares before Circles design using abstract ancestor classes Use &quot;Data-Driven&quot; approach to achieve closure   place volatile policy decisions in a separate location e.g. a file or a separate object  minimizes future change locations No program is 100% closed.
Liskov Substitution Principle All derived classes must be substitutable for their base classes This principle guides us in the creation of abstractions. Derived classes must be usable through the base class interface, without the need for the user to know the difference.
Square/Rectangle A square is-a rectangle, right? So lets consider Square as a subtype of Rectangle. void Square::SetWidth(double w) { width = w; height = w; } void Square::SetHeight(double h) { width = h; height = h; } We can  make  it work: Uh, oh. This doesn’t quite seem to fit
Substitution… denied! It is reasonable for users of a rectangle to expect that height and width may change independently. These expectations are preconditions and postconditions Bertrand Meyer calls it “Design by Contract” Post condition contract for rectangle is width = new Width height = old height Square violates Rectangle’s contract
Liskov Substitution Principle A client of rectangle expects height and width to be changed independently void setAspectRatio( Rectange* r, double ratio ); By deriving Square from Rectangle, we are allowing someone to set the aspect ratio of a Square ! We can still make it work if ( typeid(r) == typeid(Rectangle) ) Violates Open/Closed Principle !
Liskov Substitution Principle Design by Contract Bertrand Meyer Pre-conditions, Post-conditions, invariants Rectangle's postconditions for setWidth() width = newWidth length = oldLength Square can require no more of clients, nor promise any less Doesn't maintain invariant of length Violates the contract
Design by Contract Advertised Behavior of an object: advertised  Requirements  ( Preconditions ) advertised  Promises  ( Postconditions ) When redefining a method in a derivate class, you may only replace its  precondition by a weaker one , and its  postcondition by a stronger one B. Meyer , 1988 Derived class  services   should  require  no   more  and  promise no less   int Base::f(int x); // REQUIRE: x is odd // PROMISE: return even int int Derived::f(int x); // REQUIRE: x is int // PROMISE: return 8
LSP is about Semantics and Replacement The meaning and purpose of every method and class must be clearly documented Lack of user understanding will induce de facto violations of LSP Replaceability is crucial Whenever any class is referenced by any code in any system,  any future or existing subclasses of that class must be 100% replaceable Because, sooner or later, someone  will  substitute a subclass;  it’s almost inevitable.
Dependency Inversion Principle Details should depend on abstractions. Abstractions should not depend on details. V.
Dependency Inversion Principle I.  High-level modules should  not   depend on low-level modules.  Both should depend on abstractions. II. Abstractions should not depend on details.  Details should depend on abstractions R. Martin , 1996  OCP states the  goal ; DIP states the  mechanism A base class in an inheritance hierarchy should not know any of its subclasses Modules with detailed implementations are not depended upon, but depend themselves upon abstractions
Procedural vs. OO Architecture Procedural  Architecture Object-Oriented  Architecture
DIP Applied on Example Copy Reader Writer Keyboard Reader Printer Writer class Reader { public:  virtual int read()=0; }; class Writer { public:  virtual void write(int)=0; }; void Copy(Reader& r, Writer& w){ int c; while((c = r.read()) != EOF) w.write(c); } Disk Writer
Interface Segregation Principle Sometimes class methods have various groupings. These classes are used for different purposes. Not all users rely upon all methods. This lack of cohesion can cause serious dependency problems These problems can be refactored away. Helps deal with “fat” or inappropriate interfaces
Interface Pollution by “collection” Distinct clients of our class have distinct interface needs.
A Segregated Example
ATM UI Example
A Segregated ATM UI Example
Logger Example
Four Class Design Principles - Review OCP:  Extend function without editing code LSP: Child instances substitute cleanly for base DIP: Depend on abstractions instead of details ISP: Split interfaces to manage dependencies
Thank you Please write you queries to  [email_address] www.sudarsun.in

Object Oriented Design

  • 1.
    Object Oriented DesignSudarsun S., M.Tech Director – R & D Checktronix India Pvt Ltd Chennai 600010
  • 2.
    Objectives To explainhow a software design may be represented as a set of interacting objects that manage their own state and operations To introduce various models that describe an object-oriented design To introduce design patterns
  • 3.
    What is anOBJECT An instance of a CLASS Contains meaningful data Concepts that occupy memory space at runtime are, according to the definition, objects If not, they are CLASSES For example: data type vs. double
  • 4.
    A little Quiz…#1 Class or Object? Dog is a generalization of Scooby-Doo Dog Scooby-Doo
  • 5.
    A little Quiz(cont’d)… #2 Class or Object? The concept of subclass ! Dog is a subclass of the Animal class Animal is a generalization of Dog Dog Scooby-Doo Animal
  • 6.
    A little Quiz(cont’d)… #3 Class or Object? The concept of polymorphism ! Animal Dog Bird
  • 7.
    Characteristics of OODObjects are abstractions of real-world or system entities and manage themselves Objects are independent and encapsulate state and representation information. System functionality is expressed in terms of object services Shared data areas are eliminated Objects communicate by message passing Objects may be distributed Objects may execute sequentially or in parallel
  • 8.
  • 9.
    Advantages of OODEasier maintenance. Objects may be understood as stand-alone entities Objects are appropriate reusable components For some systems, there may be an obvious mapping from real world entities to system objects
  • 10.
    Object-oriented development Object-orientedanalysis, design and programming are related but distinct OOA is concerned with developing an object model of the application domain OOD is concerned with developing an object-oriented system model to implement requirements OOP is concerned with realising an OOD using an OO programming language such as Java or C++
  • 11.
    Objects and objectclasses Objects are entities in a software system which represent instances of real-world and system entities Object classes are templates for objects Classes may be used to create objects Object classes may inherit attributes and services from other object classes
  • 12.
    Object communication Conceptually,objects communicate by message passing Messages The name of the service requested by the calling object. Copies of the information required to execute the service and the name of a holder for the result of the service. In practice, messages are often implemented by procedure (a.k.a. method) calls Name = method name Information = parameter list Result holder = method return value
  • 13.
    Message examples //Call a method associated with a buffer // object that returns the next value // in the buffer v = circularBuffer.Get() ; // Call the method associated with a // thermostat object that sets the // temperature to be maintained thermostat.setTemp(20) ;
  • 14.
    Generalisation and inheritanceObjects are members of classes which define attribute types and operations Classes may be arranged in a class hierarchy where one class (a super-class) is a generalisation of one or more other classes (sub-classes) A sub-class inherits the attributes and operations from its super class and may add new methods or attributes of its own It is a reuse mechanism at both the design and the programming level Inheritance introduces complexity and this is undesirable, especially in critical systems
  • 15.
  • 16.
    Object Relationships Objectsand object classes participate in relationships with other objects and object classes In UML, such a relationship is indicated by an association Associations may be annotated with information that describes the association
  • 17.
    Object identification Identifyingobjects (or object classes) is the most difficult part of object oriented design There is no “magic formula” for object identification It relies on the skill, experience and domain knowledge of system designers Object identification is an iterative process You are unlikely to get it right first time
  • 18.
    Approaches to identificationUse a grammatical approach based on a natural language description of the system (used in HOOD method) Base the identification on tangible things in the application domain Use a behavioural approach and identify objects based on what participates in what behaviour Use a scenario-based analysis – the objects, attributes and methods in each scenario are identified
  • 19.
    Object interface specificationObject interfaces have to be specified so that the objects and other components can be designed in parallel Designers should avoid designing the interface representation but should hide this in the object itself Objects may have several interfaces which are viewpoints on the methods provided
  • 20.
    Examples of designmodels Sub-system models that show logical groupings of objects into coherent subsystems UML package diagrams Sequence models that show the sequence of object interactions UML sequence diagrams State machine models that show how individual objects change their state in response to events UML statechart diagrams Other models include use-case models, aggregation models, generalisation models,etc.
  • 21.
  • 22.
    Weather station -data collection sequence
  • 23.
    State charts Objectstates State transitions triggered by requests to objects
  • 24.
    OO Design Process– Access Layer Create Mirror classes: For every business class identified and created, create one access class. Simplify classes and their relationships – to eliminate redundant classes and structures Redundant classes: Do not keep 2 classes that perform similar request and results translation activities. Select one and eliminate the other. Methods: Revisit the classes that consist of only one or two methods to see if they can be eliminated or combined with existing classes.
  • 25.
    Object Oriented DesignProcess Design the view layer classes Design the macro & micro level user interface, identifying view layer objects Test usability and user satisfaction From the UML class diagram, begin to extrapolate the classes to build and classes to reuse. Also think about the inheritance structure. If we have several classes that seem related but have specific differences, probably it means an inheritance structure. All designed components must trace back to the user requirements.
  • 26.
  • 27.
    Example: Invoice Classesthat come to mind: Invoice , LineItem , and Customer Good idea to keep a list of candidate classes Brainstorm, simply put all ideas for classes onto the list You can cross not useful ones later
  • 28.
    Finding Classes Keepthe following points in mind: Class represents set of objects with the same behavior Entities with multiple occurrences in problem description are good candidates for objects Find out what they have in common Design classes to capture commonalities Represent some entities as objects, others as primitive types Should we make a class Address or use a String? Not all classes can be discovered in analysis phase Some classes may already exist
  • 29.
    CRC Card CRCCard Describes a class, its responsibilities, and its collaborators Use an index card for each class Pick the class that should be responsible for each method (verb) Write the responsibility onto the class card Indicate what other classes are needed to fulfill responsibility (collaborators)
  • 30.
  • 31.
    Self Check Supposethe invoice is to be saved to a file. Name a likely collaborator. Looking at the invoice, what is a likely responsibility of the Customer class? What do you do if a CRC card has ten responsibilities?
  • 32.
    Answers FileWriter To produce the shipping address of the customer. Reword the responsibilities so that they are at a higher level, or come up with more classes to handle the responsibilities.
  • 33.
    Relationships Between ClassesInheritance Aggregation Dependency
  • 34.
    Inheritance Is-a relationship Relationship between a more general class (superclass) and a more specialized class (subclass) Every savings account is a bank account Continued…
  • 35.
    Inheritance Every circleis an ellipse (with equal width and height) It is sometimes abused Should the class Tire be a subclass of a class Circle ? The has-a relationship would be more appropriate
  • 36.
    Aggregation Has-a relationship Objects of one class contain references to objects of another class Use an instance variable A tire has a circle as its boundary: Every car has a tire (in fact, it has four) class Tire { . . . private String rating; private Circle boundary; }
  • 37.
    Example class Carextends Vehicle { . . . private Tire[] tires; }
  • 38.
    Example UML Notationfor Inheritance and Aggregation
  • 39.
    Dependency Uses relationship Example: many of our applications depend on the Scanner class to read input Aggregation is a stronger form of dependency Use aggregation to remember another object between method calls
  • 40.
    UML Relationship SymbolsOpen Dotted Dependency Diamond Solid Aggregation Triangle Dotted Interface Implementation Triangle Solid Inheritance Arrow Tip Line Style Symbol Relationship
  • 41.
    Self Check Considerthe Bank and BankAccount classes. How are they related? Consider the BankAccount and SavingsAccount objects. How are they related? Consider the BankAccountTester class. Which classes does it depend on?
  • 42.
    Answers Through aggregation.The bank manages bank account objects. Through inheritance. The BankAccount , System , and PrintStream classes.
  • 43.
    Attributes and Methodsin UML Attributes and Methods in a Class Diagram
  • 44.
    Multiplicities any number(zero or more): * one or more: 1..* zero or one: 0..1 exactly one: 1 An Aggregation Relationship with Multiplicities
  • 45.
    Aggregation and AssociationAssociation: more general relationship between classes Use early in the design phase A class is associated with another if you can navigate from objects of one class to objects of the other Given a Bank object, you can navigate to Customer objects Continued…
  • 46.
    Aggregation and AssociationAn Association Relationship
  • 47.
    Five-Part Development ProcessGather requirements Use CRC cards to find classes, responsibilities, and collaborators Use UML diagrams to record class relationships Use javadoc to document method behavior Implement your program
  • 48.
    Printing an Invoice– Requirements Task: print out an invoice Invoice: describes the charges for a set of products in certain quantities Omit complexities Dates, taxes, and invoice and customer numbers Print invoice Billing address, all line items, amount due Line item Description, unit price, quantity ordered, total price For simplicity, do not provide a user interface Test program: adds line items to the invoice and then prints it Continued…
  • 49.
  • 50.
    CRC Cards Discoverclasses Nouns are possible classes Invoice Address LineItem Product Description Price Quantity Total Amount Due
  • 51.
    CRC Cards Analyzeclasses Invoice Address LineItem // Records the product and the quantity Product Description // Field of the Product class Price // Field of the Product class Quantity // Not an attribute of a Product Total // Computed–not stored anywhere Amount Due // Computed–not stored anywhere Continued…
  • 52.
    CRC Cards Classesafter a process of elimination Invoice Address LineItem Product
  • 53.
    CRC Cards forPrinting Invoice Invoice and Address must be able to format themselves:
  • 54.
    CRC Cards forPrinting Invoice Add collaborators to invoice card:
  • 55.
    CRC Cards forPrinting Invoice Product and LineItem CRC cards:
  • 56.
    CRC Cards forPrinting Invoice Invoice must be populated with products and quantities:
  • 57.
    Printing an Invoice– UML Diagrams The Relationships Between the Invoice Classes
  • 58.
    Method Documentation Use javadoc documentation to record the behavior of the classes Leave the body of the methods blank Run javadoc to obtain formatted version of documentation in HTML format Advantages: Share HTML documentation with other team members Format is immediately useful: Java source files Supply the comments of the key methods
  • 59.
    Method Documentation – Invoice class /** Describes an invoice for a set of purchased products. */ public class Invoice { /** Adds a charge for a product to this invoice. @param aProduct the product that the customer ordered @param quantity the quantity of the product */ public void add(Product aProduct, int quantity) { } /** Formats the invoice. @return the formatted invoice */ public String format() { } }
  • 60.
    Method Documentation – LineItem class /** Describes a quantity of an article to purchase and its price. */ public class LineItem { /** Computes the total cost of this line item. @return the total price */ public double getTotalPrice() { } /** Formats this item. @return a formatted string of this line item */ public String format() { } }
  • 61.
    Method Documentation – Product class /** Describes a product with a description and a price. */ public class Product { /** Gets the product description. @return the description */ public String getDescription() { } /** Gets the product price. @return the unit price */ public double getPrice() { } }
  • 62.
    Method Documentation – Address class /** Describes a mailing address. */ public class Address { /** Formats the address. @return the address as a string with three lines */ public String format() { } }
  • 63.
    Implementation Invoice aggregates Address and LineItem Every invoice has one billing address An invoice can have many line items: public class Invoice { . . . private Address billingAddress; private ArrayList<LineItem> items; }
  • 64.
    Implementation A lineitem needs to store a Product object and quantity: public class LineItem { . . . private int quantity; private Product theProduct; }
  • 65.
    Implementation The methodsthemselves are now very easy Example: getTotalPrice of LineItem gets the unit price of the product and multiplies it with the quantity /** Computes the total cost of this line item. @return the total price */ public double getTotalPrice() { return theProduct.getPrice() * quantity; }
  • 66.
    Self Check Whichclass is responsible for computing the amount due? What are its collaborators for this task? Why do the format methods return String objects instead of directly printing to System.out ?
  • 67.
    Answers The Invoice class is responsible for computing the amount due. It collaborates with the LineItem class. This design decision reduces coupling. It enables us to reuse the classes when we want to show the invoice in a dialog box or on a web page.
  • 68.
    Suh’s Axioms ofOOD The independence axiom: Maintain independence of components. Each component must satisfy its requirements without affecting other requirements. The information axiom: Minimize the information content of the design. It is concerned with simplicity. Rely on Occam’s Razor
  • 69.
    Occum’s Razor ruleof simplicity The best designs usually involve the least complex code but not necessarily the fewest number of classes or methods. Minimizing complexity should be the goal, because that produces the most easily maintained and enhanced application. In an object-oriented system, the best way to minimize complexity is to use inheritance and the system’s built-in classes and to add as little as possible to what already is there.
  • 70.
    Some Corollaries… Uncoupleddesign Single purpose Large number of simple classes Strong mapping Standardization Design with inheritance
  • 71.
    Uncoupled Design Couplingis a measure of the strength of association established by a connection from one object or software component to another. Types Interaction coupling amount and complexity of messages between components. Preferred to be minimal What happens when high and low ? Inheritance coupling coupling between super and sub classes coupling in terms of attributes and methods Preferred to be high What happens when high and low ? { override all, unused methods }
  • 72.
    Cohesion Cohesion reflectsthe “single-purposeness” of an object. Highly cohesion  Lower coupling Method cohesion: method carrying one function. A method that carries multiple functions is undesirable. Class cohesion: All the class’s methods and attributes are highly cohesive, meaning to be used by internal methods or derived classes’ methods.
  • 73.
    Corollary 2: Single Purpose Every class should be clearly defined and necessary in the context of achieving the system’s goals. When we document a class, we should be able to explain its purpose in a sentence or two. If we cannot, then the class should be subdivided into independent pieces. Each method must provide only one service. Each method should be of moderate size, no more than a page; half a page is better.
  • 74.
    Achieving Multiple InheritanceWhat is Single inheritance? What is the problem with Multiple Inheritance ? What is the ideal case for MI ? In C++ objects can inherit behavior from unrelated areas of the class tree. How to determine which behavior to get from which class, particularly when several ancestors define the same method. Virtual Inheritance !!??
  • 75.
    Class Visibility Purposeof Access Specifiers ? Difference between c++ struct and class ? The class’s protocol or the messages that a class understands, can be hidden from other objects (private protocol) or made available to other objects (public protocol). Public protocols define the functionality and external messages of an object. Private protocols define the implementation of an object. The lack of well-designed protocol can manifest itself as encapsulation leakage. It happens when details about a class’s internal implementation are disclosed through the interface
  • 76.
    Design patterns Adesign pattern is a way of reusing abstract knowledge about a problem and its solution Patterns are devices that allow programs to share knowledge about their design A pattern is a description of the problem and the essence of its solution Documenting patterns is one way to reuse and share the information about how it is best to solve a specific design problem A pattern should be sufficiently abstract to be reused in different settings Patterns often rely on object characteristics such as inheritance and polymorphism
  • 77.
    Pattern elements NameA meaningful pattern identifier Problem description Solution description Not a concrete design but a template for a design solution that can be instantiated in different ways Consequences The results and trade-offs of applying the pattern
  • 78.
    Types of PatternsCreational Abstract Factory Structural Adapter Façade Proxy Behavioral Observer Mediator
  • 79.
    Patterns by Example:Multiple displays enabled by Observer A=10% B=40% C=30% D=20% Application data A B C D A D C B Relative Percentages Y 10 40 30 20 X 15 35 35 15 Z 10 40 30 20 A B C D Change notification Requests, modifications
  • 80.
    The Observer patternName Observer Description Separates the display of object state from the object itself Problem description Used when multiple displays of state are needed Solution description See slide with UML description Consequences Optimisations to enhance display performance are impractical
  • 81.
    The Observer patternobserverState= subject  getState(); Subject attach (Observer) detach (Observer) Notify () Observer Update() Concrete Observer Update() observerState Concrete Subject GetState() SetState() subjectState observers subject For all x in observers{ x  Update(); }
  • 82.
    The Mediator PatternDescription Define an object that encapsulates how a set of objects interact Mediator promotes loose coupling by keeping objects from referring to each other explicitly It lets you vary their interaction independently Applicability Complex interaction exists You do not want to bury the interaction in the objects Distributed behavior should be customizable without a lot of sub classing Consequences Limits sub classing Decouples colleagues Simplifies object protocols Abstracts how objects cooperate Centralizes control
  • 83.
  • 84.
    The Façade PatternDescription Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Applicability Need to provide a simple interface to a complex system Need to decouple a subsystem from its clients Need to provide an interface to a software layer Consequences Shields clients from subsystem components Promotes weak coupling between the subsystem and its clients
  • 85.
    Facade Pattern: Problem Subsystem classes Client Classes Need to communicate with
  • 86.
    Facade Pattern: Solution Subsystem classes Fac ade Client Classes
  • 87.
  • 88.
    The Proxy PatternDescription Provide a surrogate or placeholder for another object to control access to it. Applicability Remote proxies can hide the fact that a real object is in another address space Virtual proxies can create expensive objects on demand. Protection proxies can control access to an object. Smart references can perform additional action above a simple pointer
  • 89.
  • 90.
    The Adapter PatternDescription Convert the interface of a class into another interface clients expect Adapter lets classes work together that could not otherwise because of incompatible interfaces Applicability Need to use an existing class whose interface does not match Need to make use of incompatible classes Consequences Class adapter commits to the concrete Adapter class Class adapter introduces only one object and no pointer indirection
  • 91.
  • 92.
    The Abstract FactoryPattern Description Provides an interface for creating families of related or dependent objects without specifying their concrete classes. Applicability Need to abstract from details of implementation of products Need to have multiple families of products Need to enforce families of products that must be used together Need to hide product implementations and just present interfaces Consequences Isolates concrete classes Makes exchanging product families easy Promotes consistency among products Supporting new kinds (in each family) of products is difficult
  • 93.
    The Abstract FactoryPattern AbstractFactory CreateProductA() CreateProductB() ConcreteFactory1 Client ProductA1 ProductA2 AbstractProductA ProductB2 ProductB1 AbstractProductB ConcreteFactory2 CreateProductA() CreateProductB()
  • 94.
    Abstract Factory ExampleWidgetFactory CreateScrollbar() CreateWindow() Window ScrollBar WWidgetFactory MacWidgetFactory Client WWindow MacWindow MacScrollBar WScrollBar One for each standard.
  • 95.
    What is dependencymanagement? What bearing does DM have on software? What is the result of poor DM? What is the advantage of good DM? Dependency Management
  • 96.
    What is dependencymanagement? A simple idea - as interdependencies increase, features like reusability, flexibility, and maintainability decrease. Dependency management is controlling interdependencies.
  • 97.
    What bearing doesDM have on software? Coupling and cohesion are the eternal concerns of software development One can say that OO is just a set of tools and techniques for Dependency Management
  • 98.
    What is thepenalty for practicing poor DM? It is rigid It is fragile It is not reusable It has high viscosity A system with poor dependency structure will typically exhibit these four negative traits:
  • 99.
    It is RigidThe impact of a change cannot be predicted If not predicted, it cannot be estimated Time and cost cannot be quantified Managers become reluctant to authorize change Official Rigidity for “Roach Motel” modules Rigidity is the inability to be changed
  • 100.
    Changes with RigidityThe System Officially Rigid Area Where the change should be made Where the change must be made now Are we containing risk, or spreading rot?
  • 101.
    It is FragileA single change requires a cascade of subsequent changes New errors appear in areas that seem unconnected to the changed areas Quality is unpredictable. The development team loses credibility Software changes seem to exhibit non-local effects
  • 102.
    Increasing Risk Defectsv. Cumulative Modifications Systems tend to become increasingly fragile over time. Intentional, planned partial rewrites may be necessary to sustain growth and maintenance. Changes Probability of introducing a bug 1.0
  • 103.
    It is notreusable Desirable parts of the design are dependent upon undesirable parts The work and risk of extracting the desirable part may exceed the cost of redeveloping from scratch.
  • 104.
  • 105.
    It has highviscosity When the “right changes” are much more difficult than hacking, the viscosity of the system is high. Over time, it will become increasingly difficult to continue developing the product. Viscosity is resistance to fluid motion.
  • 106.
    What is thebenefit of good DM? Interdependencies are managed, with firewalls separating aspects that need to vary independently. Fewer Trailers Slow the rot More Flexible Less fragile, the bugs are boxed in Easier to reuse Easier to make the right change
  • 107.
    What causes “CodeRot”? A case study “The Copy Routine” It’s been blamed on stupidity, lack of discipline, and phases of the moon, but...
  • 108.
    First Version Alldesigns start well The program is an overnight success! How could it be more simple, elegant, and maintainable? void copy(void) { int ch; while( (ch=ReadKeyboard()) != EOF) WritePrinter(ch); }
  • 109.
    Second Version Wesometimes want to read from paper tape reader. We could put a parameter in the call, but we have hundreds of users already! No big deal, this is just an exception… we can make it work. Oh, no! Nobody said the requirements might change!
  • 110.
    Second Version Designbool GtapeReader = false; // remember to clear void copy(void) { int ch; while( (ch=GtapeReader ? ReadTape() : ReadKeyboard()) != EOF) WritePrinter(ch); }
  • 111.
    Third Version Howunexpected! Requirements changed again! bool GtapeReader = false; Bool GtapePunch = false; // remember to clear void copy(void) { int ch; while( (ch=GtapeReader ? ReadTape() : ReadKeyboard()) != EOF) GtapePunch ? WritePunch(ch) : WritePrinter(ch); } It seems that sometimes we need to write to a paper tape punch. We’ve had this problem before, and just added a flag. Looks like it should work again.
  • 112.
    Example of aGood Design First and only version. void Copy() { int c; while( (c=getchar()) != EOF) putchar(c); } But wait! Aren’t we supposed to be learning OO design? This isn’t OO is it?
  • 113.
    … is it?FILE is an abstraction It represents some kind of byte stream It has many variations It has methods Read, Write, getchar, putchar, etc The methods are *dynamically* bound It is a small program based on abstractions! FILE is a class, just implemented differently.
  • 114.
    Rephrased in OOinterface Reader { char read(); } interface Writer { void write(char c); } public class Copy { Copy(Reader r, Writer w) { itsReader = r; itsWriter = w; } public void copy() { int c; while( (c==itsReader.read()) != EOF ) itsWriter.write(c); } private Reader itsReader; private Writer itsWriter; }
  • 115.
    Class Design PrinciplesS RP: The Single Responsibility Principle O CP: The Open/Closed Principle L SP: The Liskov Substitution Principle I SP: The Interface Segregation Principle D IP: The Dependency Inversion Principle From: Agile Software Development: Principles, Patterns, and Practices. Robert C. Martin, Prentice Hall, 2002.
  • 116.
    The Single ResponsibilityPrinciple A class should have one, and only one, reason to change.
  • 117.
    Open/Closed Principle Aprinciple which states that we should add new functionality by adding new code, not by editing old code. Defines a lot of the value of OO programming Abstraction is the key “ Modules should be open for extension, but closed for modification” -Bertrand Meyer
  • 118.
    Abstraction is KeyClient/Server relationships are “open” Changes to servers cause changes to clients Abstract servers “close” clients to changes in implementation. Abstraction is the most important word in OOD
  • 119.
    The Shape ExampleProcedural (not closed) implementation OO (closed) implementation
  • 120.
    Procedural (open) versionenum ShapeType {circle, square}; struct Shape {enum ShapeType itsType;}; struct Circle { enum ShapeType itsType; double itsRadius; Point itsCenter; }; void DrawCircle(struct Circle*) struct Square { enum ShapeType itsType; double itsSide; Point itsTopLeft; }; void DrawSquare(struct Square*) #include <Shape.h> #include <Circle.h> #include <Square.h> typedef struct Shape* ShapePtr; void DrawAllShapes(ShapePtr list[], int n) { int i; for( i=0; i< n, i++ ) { ShapePtr s = list[i]; switch ( s->itsType ) { case square: DrawSquare((struct Square*)s); break; case circle: DrawCircle((struct Circle*)s); break; } } } Shape.h Circle.h Square.h DrawAllShapes.c
  • 121.
    What is wrongwith the code? DrawAllShapes is not closed. Switch/case tend to recur in diverse places. If we add a shape, we add to the switch/case All switch/case statements must be found and editd. Switch/Case statements are seldom this tidy When we add to the enum, we must rebuild everything The software is both rigid and brittle It can be demonstrated to work. Isn’t that the important thing?
  • 122.
    A Closed ImplementationClass Shape { public: virtual void Draw() const =0; }; #include <Shape.h> void DrawAllShapes(Shape* list[],int n) { for(int i=0; i< n; i++) list[i]->draw(); } Shape.h DrawAllShapes.cpp Circle.h Square.h Class Square: public Shape { public: virtual void Draw() const; }; Class Circle: public Shape { public: virtual void Draw() const; };
  • 123.
    Strategic Closure ClosureAgainst What? Closure is strategic. You have to choose which changes you’ll isolate yourself against. What if we have to draw all circles first? Now DrawAllShapes must be edited (or we have to hack something) Opened Where? Somewhere, someone has to instantiate the individual shapes. It’s best if we can keep the dependencies confined Use abstraction to gain explicit closure provide class methods which can be dynamically invoked to determine general policy decisions e.g. draw Squares before Circles design using abstract ancestor classes Use &quot;Data-Driven&quot; approach to achieve closure place volatile policy decisions in a separate location e.g. a file or a separate object minimizes future change locations No program is 100% closed.
  • 124.
    Liskov Substitution PrincipleAll derived classes must be substitutable for their base classes This principle guides us in the creation of abstractions. Derived classes must be usable through the base class interface, without the need for the user to know the difference.
  • 125.
    Square/Rectangle A squareis-a rectangle, right? So lets consider Square as a subtype of Rectangle. void Square::SetWidth(double w) { width = w; height = w; } void Square::SetHeight(double h) { width = h; height = h; } We can make it work: Uh, oh. This doesn’t quite seem to fit
  • 126.
    Substitution… denied! Itis reasonable for users of a rectangle to expect that height and width may change independently. These expectations are preconditions and postconditions Bertrand Meyer calls it “Design by Contract” Post condition contract for rectangle is width = new Width height = old height Square violates Rectangle’s contract
  • 127.
    Liskov Substitution PrincipleA client of rectangle expects height and width to be changed independently void setAspectRatio( Rectange* r, double ratio ); By deriving Square from Rectangle, we are allowing someone to set the aspect ratio of a Square ! We can still make it work if ( typeid(r) == typeid(Rectangle) ) Violates Open/Closed Principle !
  • 128.
    Liskov Substitution PrincipleDesign by Contract Bertrand Meyer Pre-conditions, Post-conditions, invariants Rectangle's postconditions for setWidth() width = newWidth length = oldLength Square can require no more of clients, nor promise any less Doesn't maintain invariant of length Violates the contract
  • 129.
    Design by ContractAdvertised Behavior of an object: advertised Requirements ( Preconditions ) advertised Promises ( Postconditions ) When redefining a method in a derivate class, you may only replace its precondition by a weaker one , and its postcondition by a stronger one B. Meyer , 1988 Derived class services should require no more and promise no less int Base::f(int x); // REQUIRE: x is odd // PROMISE: return even int int Derived::f(int x); // REQUIRE: x is int // PROMISE: return 8
  • 130.
    LSP is aboutSemantics and Replacement The meaning and purpose of every method and class must be clearly documented Lack of user understanding will induce de facto violations of LSP Replaceability is crucial Whenever any class is referenced by any code in any system, any future or existing subclasses of that class must be 100% replaceable Because, sooner or later, someone will substitute a subclass; it’s almost inevitable.
  • 131.
    Dependency Inversion PrincipleDetails should depend on abstractions. Abstractions should not depend on details. V.
  • 132.
    Dependency Inversion PrincipleI. High-level modules should not depend on low-level modules. Both should depend on abstractions. II. Abstractions should not depend on details. Details should depend on abstractions R. Martin , 1996 OCP states the goal ; DIP states the mechanism A base class in an inheritance hierarchy should not know any of its subclasses Modules with detailed implementations are not depended upon, but depend themselves upon abstractions
  • 133.
    Procedural vs. OOArchitecture Procedural Architecture Object-Oriented Architecture
  • 134.
    DIP Applied onExample Copy Reader Writer Keyboard Reader Printer Writer class Reader { public: virtual int read()=0; }; class Writer { public: virtual void write(int)=0; }; void Copy(Reader& r, Writer& w){ int c; while((c = r.read()) != EOF) w.write(c); } Disk Writer
  • 135.
    Interface Segregation PrincipleSometimes class methods have various groupings. These classes are used for different purposes. Not all users rely upon all methods. This lack of cohesion can cause serious dependency problems These problems can be refactored away. Helps deal with “fat” or inappropriate interfaces
  • 136.
    Interface Pollution by“collection” Distinct clients of our class have distinct interface needs.
  • 137.
  • 138.
  • 139.
    A Segregated ATMUI Example
  • 140.
  • 141.
    Four Class DesignPrinciples - Review OCP: Extend function without editing code LSP: Child instances substitute cleanly for base DIP: Depend on abstractions instead of details ISP: Split interfaces to manage dependencies
  • 142.
    Thank you Pleasewrite you queries to [email_address] www.sudarsun.in