Oo Design Rules 2012

Embed Size (px)

Citation preview

  • 8/10/2019 Oo Design Rules 2012

    1/50

    ceCS 5751

    7 Object-oriented Design Principles

    1. Favor Composition Over Inheritance2. Program To An I nterface, Not An Implementation

    3. The Open-Closed Principle: Software Entities ShouldBe Open For Extension, Yet Closed For Modification

    4. The L iskov Substitution Pr inciple: Functions ThatUse References To Base Classes Must Be Able To UseObjects Of Derived Classes Without Knowing It

    5. TheLaw of Demeter6. Minimize The Accessibility of Classes and Members

    7. The Dependency Inversion Principle

  • 8/10/2019 Oo Design Rules 2012

    2/50

    ceCS 5752

    Favor Composition Over Inheritance

    Composition- Method of reuse in which newfunctionality is obtained by creating an objectcomposed of other objects

    The new functionality is obtained by delegating

    functionality to one of the objects being composed Sometimes called aggregation or containment,

    although some authors give special meanings tothese terms

  • 8/10/2019 Oo Design Rules 2012

    3/50

    ceCS 5753

    Favor Composition Over Inheritance

    For example:Aggregation - when one object owns or is responsible

    for another object and both objects have identicallifetimes (GoF)

    Aggregation - when one object has a collection ofobjects that can exist on their own (UML)

    Containment - a special kind of composition inwhich the contained object is hidden from otherobjects and access to the contained object is only via

    the container object (Coad)

  • 8/10/2019 Oo Design Rules 2012

    4/50

    ceCS 5754

    Advantages/Disadvantages Of Composition

    Advantages: Contained objects are accessed by the containing class solely

    through their interfaces

    "Black-box" reuse, since internal details of contained objects arenot visible

    Good encapsulation Fewer implementation dependencies

    Each class is focused on just one task

    The composition can be defined dynamically at run-time throughobjects acquiring references to other objects of the same type

    Disadvantages:

    Resulting systems tend to have more objects

    Interfaces must be carefully defined in order to use many differentobjects as composition blocks

  • 8/10/2019 Oo Design Rules 2012

    5/50

    ceCS 5755

    Inheritance

    Method of reuse in which new functionality is obtained byextending the implementation of an existing object

    The generalization class (the base class) explicitly captures thecommon attributes and methods

    The specialization class (the derived class) extends theimplementation with additional attributes and methods

    You can choose your associates, but youre stuck with yourancestors.

    Inheritance is often held to be sacrosanct in OOD.

    Tendency for OO developers to gauge the success of theirefforts by the complexity of their inheritance hierarchy.

  • 8/10/2019 Oo Design Rules 2012

    6/50

    ceCS 5756

    Advantages/Disadvantages Of Inheritance

    Advantages: New implementation is easy, since most of it is inherited

    Easy to modify or extend the implementation being reused

    Disadvantages:

    Breaks encapsulation, since it exposes a derived class toimplementation details of its base class

    White-box" reuse, since internal details of base classes are oftenvisible to derived classes

    Derived classes may have to be changed if the implementation of thebase class changes

    Implementations inherited from base classes can not be changed atruntime

  • 8/10/2019 Oo Design Rules 2012

    7/50

    ceCS 5757

    Inheritance occurs in two types

    1. Implementation Inheritance inheritance of implementation fragments/code from a base class.

    2. Interface Inheritance

    inheritance of contract fragments/interfaces.

    Inheritance is a complex issue. Basic notions differ among OO languages

    Some controversial issues--e.g. multiple inheritance.

    Inheritance can break encapsulation.

    Poorly conceived inheritance relationships can frustrate system

    reliability, maintainability, and evolvability.

    Inheritance is neither inherently good or bad. It must be usedin a disciplined manner.

  • 8/10/2019 Oo Design Rules 2012

    8/50

    ceCS 5758

    A Wacky Inheritance Example

    An example of multiple inheritance from an OO text

    Of course, a pie is not a fruit

  • 8/10/2019 Oo Design Rules 2012

    9/50

    ceCS 5759

    Composed Pie

    Pies (and most objects in the world) are combinations ofproperties from divergent sources.

  • 8/10/2019 Oo Design Rules 2012

    10/50

    ceCS 57510

    Example Two

    Inheritance is generally not appropriate for is a role playedby relationships.

    For instance, consider roles in an airline reservation system:

    passenger

    ticket agent

    flight crew

    etc.

  • 8/10/2019 Oo Design Rules 2012

    11/50

    ceCS 57511

    Problems with Example 2

    What happens if a pilot doubles as mechanic. And triples as aticket agent?

  • 8/10/2019 Oo Design Rules 2012

    12/50

    ceCS 57512

    Composition Version

    Sometimes called delegation

    I h it V C iti

  • 8/10/2019 Oo Design Rules 2012

    13/50

    ceCS 57513

    Inheritance Versus Composition--Some Guidelines

    It is generally not a good idea to use inheritance for thefollowing purposes:

    To represent dynamically changing alternative roles of a base class

    To hide methods or attributes inherited from a base class.

    To implement a domain-specific class as a derived class of a utility

    class.

    Potential Drawbacks of Composition

    There may be some minor performance penalty for invoking anoperation across object boundaries as opposed to using an inheritedmethod.

    Delegation cant be used with partially abstract (uninstantiable)classes

    Delegation does not, in and of itself, impose any disciplinedstructure on the design (but neither does a class hierarchy).

  • 8/10/2019 Oo Design Rules 2012

    14/50

    ceCS 57514

    Coad's Rules

    Use inheritance only when all of the following criteria aresatisfied:

    A derived class expresses "is a special kind of" and not "is arole played by a"

    An instance of a derived class never needs to become an objectof another class (transmutes)

    A derived class extends, rather than overrides or nullifies, theresponsibilities of its base class

    A derived class does not extend the capabilities of what is

    merely a utility class

    For a class in the actual Problem Domain, the derived classspecializes a role, transaction or device

  • 8/10/2019 Oo Design Rules 2012

    15/50

    ceCS 57515

    Inheritance VS Composition Example 1

  • 8/10/2019 Oo Design Rules 2012

    16/50

    ceCS 57516

    Inheritance VS Composition Example 1

    "Is a special kind of" not "is a role played by a" Fail. A passenger is a role a person plays. So is an agent.

    Never needs to transmute

    Fail. A instance of a subclass of Person could change from Passengerto Agent to Agent Passenger over time

    Extends rather than overrides or nullifies

    Pass.

    Does not extend a utility class

    Pass.

    Within the Problem Domain, specializes a role, transaction ordevice

    Fail. A Person is not a role, transaction or device.

    Inheritance not appropriate in this situation

  • 8/10/2019 Oo Design Rules 2012

    17/50

    ceCS 57517

    Inheritance VS Composition Example 1

    Use composition to complete the relationships

  • 8/10/2019 Oo Design Rules 2012

    18/50

    ceCS 57518

    Inheritance VS Composition Example 2

    Is inheritance okay here?

  • 8/10/2019 Oo Design Rules 2012

    19/50

    ceCS 57519

    Inheritance VS Composition Example 2

    "Is a special kind of" not "is a role played by a" Pass. Passenger and agent are special kinds of person roles.

    Never needs to transmute

    Pass. A Passenger object stays a Passenger object; the same is truefor an Agent object.

    Extends rather than overrides or nullifies

    Pass.

    Does not extend a utility class

    Pass.

    Within the Problem Domain, specializes a role, transaction ordevice

    Pass. A PersonRole is a type of role.

    Inheritance ok here!

  • 8/10/2019 Oo Design Rules 2012

    20/50

    ceCS 57520

    Inheritance VS Composition Example 3

  • 8/10/2019 Oo Design Rules 2012

    21/50

    ceCS 57521

    Inheritance VS Composition Example 3

    "Is a special kind of" not "is a role played by a"

    Pass. Reservation and purchase are a special kind of transaction.

    Never needs to transmute

    Pass. A Reservation object stays a Reservation object; the same istrue for a Purchase object.

    Extends rather than overrides or nullifies Pass.

    Does not extend a utility class Pass.

    Within the Problem Domain, specializes a role, transaction ordevice Pass. It's a transaction.

    Inheritance is okay in this situation

  • 8/10/2019 Oo Design Rules 2012

    22/50

    ceCS 57522

    Inheritance vs. Composition Summary

    Both composition and inheritance are important methods ofreuse

    Inheritance was overused in the early days of OO development

    Over time we've learned that designs can be made morereusable and simpler by favoring composition

    Of course, the available set of classes that can be composed canbe enlarged using inheritance

    So composition and inheritance work together

    But our fundamental principle is:

    Favor Composition Over Inheritance

    Program To An Interface Not An

  • 8/10/2019 Oo Design Rules 2012

    23/50

    ceCS 57523

    Program To An Interface, Not AnImplementation

    An interface is the set of methods one object knows it caninvoke on another object

    An object can have many interfaces. (Essentially, an interfaceis a subset of all the methods that an object implements).

    A type is a specific interface of an object

    Different objects can have the same type and the same objectcan have many different types

    An object is known by other objects only through its interface

    In a sense, interfaces express "is a kind of" in a very limitedway as "is a kind of that supports this interface"

    Interfaces are the key to reusability!

  • 8/10/2019 Oo Design Rules 2012

    24/50

    ceCS 57524

    Implementation Inheritance vs InterfaceInheritance

    Implementation Inheritance (Class Inheritance) - an object'simplementation is defined in terms of another's objectsimplementation

    Interface Inheritance (Subtyping) - describes when one objectcan be used in place of another object

    The C++ inheritance mechanism means both class and interfaceinheritance

    C++ can perform interface inheritance by inheriting from apure abstract class

    Java has a separate language construct for interface inheritance- the Java interface

    Java's interface construct makes it easier to express andimplement designs that focus on object interfaces

  • 8/10/2019 Oo Design Rules 2012

    25/50

  • 8/10/2019 Oo Design Rules 2012

    26/50

    ceCS 57526

    The Open-Closed Principle: Software Entities Should BeOpen For Extension, Yet Closed For Modification

    The Open-Closed Principle (OCP) says that we should attempt todesign modules that never need to be changed

    To extend the behavior of the system, we add new code. We donot modify old code.

    Modules that conform to the OCP meet two criteria:

    Open For Extension - The behavior of the module can be extended tomeet new requirements

    Closed For Modification - the source code of the module is not allowedto change

    How can we do this?

    Abstraction

    Polymorphism

    Inheritance

    Interfaces

  • 8/10/2019 Oo Design Rules 2012

    27/50

    ceCS 57527

    The Open-Closed Principle

    It is not possible to have all the modules of a software systemsatisfy the OCP, but we should attempt to minimize the numberof modules that do not satisfy it

    The Open-Closed Principle is really the heart of OO design

    Conformance to this principle yields the greatest level ofreusability and maintainability

    Open Closed Principle Open Closed

  • 8/10/2019 Oo Design Rules 2012

    28/50

    ceCS 57528

    Open-Closed Principle Open-ClosedPrinciple Example

    Consider the following method of some class:

    public double totalPrice(Part[] parts) {

    double total = 0.0;

    for (int i=0; i

  • 8/10/2019 Oo Design Rules 2012

    29/50

    ceCS 57529

    Open-Closed Principle Example ( Open-Closed PrincipleExample (Continued)

    But what if the Accounting Department decrees that motherboardparts and memory parts should have a premium applied whenfiguring the total price.

    How about the following code?public double totalPrice(Part[] parts) {

    double total = 0.0;

    for (int i=0; i

  • 8/10/2019 Oo Design Rules 2012

    30/50

    ceCS 57530

    Open-Closed Principle Example ( Open-Closed PrincipleExample (Continued)

    Does this conform to the OCP? No way! Every time the Accounting Department comes out with a new

    pricing policy, we have to modify the totalPrice() method! It isnot Closed For Modification. Obviously, policy changes suchas that mean that we have to modify code somewhere, so what

    could we do? To use our first version of totalPrice(), we could incorporate

    pricing policy in the getPrice() method of a Part

  • 8/10/2019 Oo Design Rules 2012

    31/50

    ceCS 57531

    Closed for Modification? Open for Extension?

    #include

    using namespace std;

    class pizza {

    public:

    virtual float cost()=0 {}

    };

    class small_pizza : public pizza {public:

    float cost(){

    return 10.0;

    }

    };

    class medium_pizza : publicpizza {

    public:

    float cost(){

    return 12.0;

    }

    };

    enum psize {none, small, medium};

    pizza *factory(int size) {if(size==small)

    return new small_pizza;

    else

    if(size==medium)

    return new medium_pizza;

    else

    return none;}

    int main(){

    pizza *p;

    int size;

    cout > size;

    p=factory(size);

    cout

  • 8/10/2019 Oo Design Rules 2012

    32/50

    ceCS 57532

    The Liskov Substitution Principle:

    Functions That Use References To Base (Super)Classes Must Be Able To Use Objects Of Derived(Sub) Classes Without Knowing It

    In intent, Liskov Substitution Principle (LSP) forces

    software designers to not override base classfunctionality if it affects the performance ofcomponents designed to work with the base class.

  • 8/10/2019 Oo Design Rules 2012

    33/50

    ceCS 57533

    If Sis a subtype of T, then objects of typeTmay be replaced with objects of type S

    without altering the correctness of the

    program.

    Definition

  • 8/10/2019 Oo Design Rules 2012

    34/50

    ceCS 57534

    Example

    class W {

    (..)

    void use (T obj) {

    String s = obj.getInfo()

    }

    (..)}

    objW.use(objT)

    /* no error is introduced if S is

    compliant with the principle*/

    objW.use(objS)

  • 8/10/2019 Oo Design Rules 2012

    35/50

    ceCS 57535

    Example

  • 8/10/2019 Oo Design Rules 2012

    36/50

    ceCS 57536

    Example

    /*Method to print informationabout someone on the screen*/

    void printInfo(Person obj) { ()

    parser.parseName(obj.getName());() }

    A programmer may write

    expecting this code to work for all derived types ofPerson, including Employee. This code will

    actually result in error.

    The redefinition of getName changed the behaviorof the method, and introduced an error (or severalerrors) in the program.

  • 8/10/2019 Oo Design Rules 2012

    37/50

    ceCS 57537

    LSP Summary

    In order for the LSP to hold (and with it the Open-Closed

    Principle) all subclasses must conform to the behavior that clientsexpect of the base classes they use

    A subtype must have no more constraints than its base type, sincethe subtype must be usable anywhere the base type is usable

    If the subtype has more constraints than the base type, there wouldbe uses that would be valid for the base type, but that wouldviolate one of the extra constraints of the subtype and thus violatethe LSP!

    The guarantee of the LSP is that a subclass can always be usedwherever its base class is used!

  • 8/10/2019 Oo Design Rules 2012

    38/50

    ceCS 57538

    Minimize The Accessibility of Classes and Members

    We must define several key concepts:

    abstraction,

    information hiding, and

    encapsulation,

    All three are different, independent characteristics, and allthree are possible in non-OO languages

  • 8/10/2019 Oo Design Rules 2012

    39/50

    ceCS 57539

    Abstraction

    "Abstraction is the selective examination of certain aspects of a

    problem. The goal of abstraction is to isolate those aspects that areimportant for some purpose and suppress those aspects that areunimportant."

    -- [Rumbaugh et al, 1991]

    "A view of a problem that extracts the essential informationrelevant to a particular purpose and ignores the remainder of theinformation."

    -- [IEEE, 1983]

    "An abstraction denotes the essential characteristics of an objectthat distinguish it from all other kinds of object and thus providecrisply defined conceptual boundaries, relative to the perspective ofthe viewer."

    -- [Booch, 1991]

    Abstraction is one of the fundamental ways to deal with complexity

  • 8/10/2019 Oo Design Rules 2012

    40/50

    ceCS 57540

    Information Hiding

    The second decomposition was made using 'information hiding'... as a criterion. The modules no longer correspond to steps inthe processing. ... Every module in the second decomposition ischaracterized by its knowledge of a design decision which ithides from all others. Its interface or definition was chosen toreveal as little as possible about its inner workings."

    -- [Parnas, 1972b]

    "The process of hiding all the details of an object that do notcontribute to its essential characteristics; typically, the structureof an object is hidden, as well as the implementation of its

    methods. The terms information hiding and encapsulation areusually interchangeable." -- [Booch, 1991]

    "... [I]nformation hiding: a module is characterized by theinformation it hides from other modules, which are called itsclients. The hidden information remains a secret to the clientmodules." -- [Ghezzi et al, 1991]

  • 8/10/2019 Oo Design Rules 2012

    41/50

    ceCS 57541

    Encapsulation

    "[E]ncapsulation -- also known as information hiding -- preventsclients from seeing its inside view, were the behavior of theabstraction is implemented."

    -- [Booch, 1991]

    "Encapsulation (also information hiding) consists of separatingthe external aspects of an object which are accessible to otherobjects, from the internal implementation details of the object,which are hidden from other objects."

    -- [Rumbaugh et al, 1991]

    "The concept of encapsulation as used in an object-orientedcontext is not essentially different from its dictionary definition.It still refers to building a capsule, in the case a conceptual

    barrier, around some collection of things."

    -- [Wirfs-Brock et al, 1990]

  • 8/10/2019 Oo Design Rules 2012

    42/50

    ceCS 57542

    Use Accessors and Mutators, Not Public Members

    Use private members and appropriate accessors and mutators wherever possible

    For example:

    Replace

    public double speed;

    with

    private double speed;public double getSpeed() {

    return(speed);

    }

    public void setSpeed(double newSpeed) {

    speed = newSpeed;}

  • 8/10/2019 Oo Design Rules 2012

    43/50

    ceCS 57543

    Benefits of Information Hiding

    You can put constraintson values

    public void setSpeed(double newSpeed) {

    if (newSpeed < 0) {

    sendErrorMessage(...);

    newSpeed = Math.abs(newSpeed);}

    speed = newSpeed;

    }

    If users of your class accessed the fields directly, then theywould each be responsible for checking constraints

  • 8/10/2019 Oo Design Rules 2012

    44/50

    ceCS 57544

    Benefits of Information Hiding

    You can change your internal representation without changing the interface// Now using metric units (kph, not mph)

    public void setSpeedInMPH(double newSpeed) {

    speedInKPH = convert(newSpeed);

    }

    public void setSpeedInKPH(double newSpeed) {speedInKPH = newSpeed;

    }

  • 8/10/2019 Oo Design Rules 2012

    45/50

    ceCS 57545

    Benefits of Information Hiding

    You can perform arbitrary side effects

    public double setSpeed(double newSpeed) {

    speed = newSpeed;

    notifyObservers();}

    If users of your class accessed the fields directly, then theywould each be responsible for executing side effects

  • 8/10/2019 Oo Design Rules 2012

    46/50

    ceCS 57546

    The Law of Demeter

    Only talk to your immediate friends.

    An object should assume as little as possible about the structureor properties of anything else (including its subcomponents).

    More formally, the Law of Demeter for functions requires thata methodMof an object Omay only invoke the methods of the

    following kinds of objects: Oitself

    M's parameters

    any objects created/instantiated withinM

    O's direct component (aggregated) objects

  • 8/10/2019 Oo Design Rules 2012

    47/50

    ceCS 57547

    Demeter Example

    class C {

    public:void HiC(){

    return;

    }

    };

    class P {

    public:void op1(){

    return;

    }

    };

    class DontTalk2Me {public:

    void DontTalkToMe(){

    return;

    }

    };

    DontTalk2Me dt2m;

    class O {

    C cobj;

    public:void op1(P pobj) {

    pobj.op1();

    cobj.HiC();

    dt2m.DontTalkToMe();

    }

    Void op2() {

    op1();

    };

    int main(){

    O obj;

    P p;

    obj.op1(p);

    return 0;

    }

  • 8/10/2019 Oo Design Rules 2012

    48/50

  • 8/10/2019 Oo Design Rules 2012

    49/50

  • 8/10/2019 Oo Design Rules 2012

    50/50

    Simple Example

    // Dependency Inversion Principle - Bad example

    class Worker {public void work() {

    // ....working

    }

    }

    class Manager {

    Worker m_worker;

    public void setWorker(Worker w) {

    m_worker=w;

    }

    public void manage() {

    m_worker.work();

    }}

    class SuperWorker {

    public void work() {

    //.... working much more

    }

    }

    // Dependency Inversion Principle - Good example

    interface IWorker {

    public void work();

    }

    class Worker implements IWorker{

    public void work() {

    // ....working

    }

    }

    class SuperWorker implements IWorker{public void work() {

    //.... working much more

    }

    }

    class Manager {

    IWorker m_worker;public void setWorker(IWorker w) {

    m_worker=w;

    }

    public void manage() {

    m_worker.work();

    }