Docstoc

Design Patterns and Principles of Object Oriented Application

Document Sample
Design Patterns and Principles of Object Oriented Application Powered By Docstoc
					Design Patterns and Principles of
   Object Oriented Application
          Development

 “design patterns are proven techniques
   used by experienced developers to
tackle recurring design problems without
        resorting to first principles”
Design Patterns: Elements of Reusable Object-Oriented Software
                     Gamma, Helm, Johnson and Vlissides, 1995
               Introduction

   Software Quality


   Principles of Object Oriented Design
       Methods to improve on software quality

   Design Patterns
       Principles applied
                    Software Quality
   External Factors              Internal Factors

       Visible to customers          Visible to developers

       Examples:                     Examples:
            Ease of Use
            Extendability                 Information Hiding
            Robustness                    Consistency
            Correctness                   Programming Style
          External Factors



              Correctness
The software performs according to the client's
                 specification
          External Factors



             Robustness
The software reacts reasonably to actions and
    events not covered by the specification
External Factors



      Reliability
A system is reliable if it is
        correct

            &
         robust
             Software Quality

How is Software Quality achieved?

     Software Principles
     Design Patterns

           Software principles + design patterns
                            =
                Improved Internal Factors
    Why Object Oriented Design?


   Object decomposition
       More intuitive mapping of the problem domain to
        objects
       What types of object are manipulated by the
        system?
            Objects as generalised type
            Specific behaviour given to subtypes
             Object Oriented Design
                               Benefits

   Reusability
       Operations usually dependent on data
       Objects bind data to operations
            class is the unit of reuse
       DRY – Don't Repeat Yourself

   Extendibility
       By building on existing functionality
       Object heirarchies are more stable over time as
        system is modified
                         Modularity
   Decomposition
       large problems into smaller manageable
        problems
       large or complex code base composed of
        smaller, simpler subunits
            Subunits provide specific feature or functionality
   Composition
       Build new software from existing smaller
        components (DRY)‫‏‬
                    Modularity
               Supporting Principles

   The Open-Closed Principle      Dependency Inversion
                                    Principle
   Information Hiding
                                   Liskov Substitution
   Uniform Access Principle        Principle

   Acyclic Dependency             Interface Segregation
    Principle                       Principle

   Single Responsibility          Composite Reuse Principle
    Principle
                                   Principle of Least
                                    Knowledge (Law of
                                    Demeter)
     The Open-Closed Principle
   Modules are open for extension
        Modules are coupled across abstract interfaces.
        The interfaces should provide sufficient access to be
         extended by newer code.

   Modules are closed for modification
        new features are added without modifying the system's
         existing code.
        Only bug fixes are applied to existing implementation.
        New features are added by new classes.
     The Open-Closed Principle

   Advocates always writing to interfaces or
    abstract classes

   Reduces the coupling between system
    components to the abstract layer only
The Open-Closed Principle
         Example
    Information Hiding Principle
   Each module has a defined public interface
    through which all external access must occur
       The module designer selects a subset of a
        module's properties or methods to act as this
        interface to client modules.

   A module's internal structure should be
    protected from external access
       Implementation details remain hidden
       Easier to ensure system is in a consistent/legal
        state if all access to data is secured against
        external access.
Uniform Access Principle


"All services offered by a module
  should be available through a
uniform notation, which does not
      betray whether they are
implemented through storage or
       through computation."
                     Bertrand Meyer
    Uniform Access Principle
                  Ruby Example

class UAP
  attr_reader :value
  def initialize(value)‫‏‬
    @value = value
  end
  def value_squared
    return @value*@value
  end
end

uap = UAP.new(10)‫‏‬
puts uap.value
puts uap.value_squared
     Uniform Access Principle
                     Python Example
class UAP(object):
    def __init__(self, value):
        self.setValue(value)‫‏‬

    def getValue(self):
        return self.__value

    def setValue(self, value):
        self.__value = value

    def getValueSquared(self):
        return self.__value*self.__value

    value = property(getValue, doc="getter for value")‫‏‬
    valueSquared = property(getValueSquared, doc="getter for
  value squared")‫‏‬

uap = UAP(2)‫‏‬
print uap.value
print uap.valueSquared
Acyclic Dependency Principle
   Package dependencies must not form
    cycles.
       Example: Package A imports Package B and
        Package B imports Package A

   Causes the tight coupling between
    packages.
       Package A must be deployed everywhere
        Package B is (and vice versa)

   How to break dependency cycles?
Acyclic Dependency Principle
   Factor out code that causes the dependency
    into separate package
Single Responsibility Principle
   A class should have one responsibility.

   Each responsibility can lead to modifications
    to the class on changing requirements.

   For maintainable code, if a class has multiple
    responsibilities, break up the class into
    multiple cooperating classes.
Dependency Inversion Principle


   High level classes should depend upon low
    level abstractions.

   High level class contains reference to
    abstract type to perform the function.
Dependency Inversion Principle
                        Example




 Gauge takes a string to avoid dependency on
  concrete GaugeType subclass.
 Prone to errors like typos



(See Factory Pattern)
    Liskov Substitution Principle
   Extends OCP

   A base class can be replaced by a derived
    class without changing the functionality of the
    module.

   Ensure derived classes do not change the
    behaviour of parent classes.
    Liskov Substitution Principle
                  (Contd)


 Design by contract (from Eiffel)
 Preconditions and postconditions of super

  class are maintained by subclass.
 If preconditions not met, don't invoke

  method.
 If postconditions not met, don't return.
      Liskov Substitution Principle
                                 Example
class Rectangle                  def printArea(shape)
 attr_accessor :width, :height    shape.width=5
 def area                         shape.height=10
   @width * @height               if shape.is_a? Rectangle
 end                                puts "Rectangle of 5x10 should have area of 50,"
end                               else
                                    puts "Not a Rectangle, so don't know the area"
class Square < Rectangle          end
 def width=(new_width)            puts "Shape is a #{shape.class} of #{shape.width}”
   @width=@height=new_width          + “x#{shape.height}, area is #{shape.area}"
 end                             end
 def height=(new_height)
   @width=@height=new_height     r = Rectangle.new
 end                             s = Square.new
end
                                 printArea(r)
                                 gets
                                 printArea(s)
           Integration Segregation
                  Principle
   Many specific interfaces are better than a
    large generic interface.
       Classes should not be forced to implement an
        interface they do not use.

   Is large interface really representative of
    most general type?
       Null operation or default methods?

   Reduces amount of information shared
    between modules.
        Composite Reuse Principle
 Don't define default behaviour in base
  classes
 Prefer polymorphic composition of objects

  over inheritance
       Instance variables are references to abstract type
        of concrete classes providing functionality


See Strategy, Composite and Visitor Patterns
    Principle of Least Knowledge
        (aka Law of Demeter)‫‏‬
 When calling method M of object O, M may
  only access methods on:
 O

 Parameters of M

 Objects created by M

 O's contained instance objects

 M cannot call through to methods exposed

  by objects outside of it's control:
       Example:
         object.field.method()
       Design Patterns

   Proven 'best practices'

   High level building blocks for
    system architecture

   Resulted from the experiences of
    their implementation across a
    number of scenarios.
        Common Design Patterns
   Creational
       Singleton
       Factory        Structural
       Builder
                           Decorator
   Behavioural            Facade
                           Composite
       Strategy
       Visitor
       Observer
                    Singleton
   When only a single instance of a class should be
    created for the entire application.
class Singleton {
    private static Singleton instance;
    private Singleton() {
            ...
    }
    public static synchronized Singleton getInstance()
  {
           if (instance == null)‫‏‬
                   instance = new Singleton();
           return instance;
    }

     public void doSomething() {
            ...
     }
                        Builder
   Create complex objects while hiding the
    complexity of the objects' creation behind an
    interface.

   The Builder pattern is indicated when the
    complex object can have different
    representations/implementations.
       client is shielded from these differences in
        construction
Builder
Example
                       Factory

   Allows clients to create objects of abstract
    types without depending on concrete
    subclasses.

   Two types:
       Abstract Factory

       Factory Method
                  Abstract Factory
   Provides an interface to create families of
    objects without the client specifying the
    concrete type
       System can use of a multiple families of products
            e.g. wxWidgets or Qt window toolkits

       Clients rely on interfaces, not concrete
        implementations
Abstract Factory
     Example
                Factory Method
   Expose an interface for creating an object

   Subclasses determine the concrete type to
    instantiate
       May delegate responsibility to helper classes to
        localise the knowledge of object's construction
Factory Method
    Example
          Factory versus Builder
   Factory Method creates concrete object
       Akin to a virtual constructor
       Returns different subtypes depending on input

   Abstract Factory creates families of objects
       Factory class may contain Factory Method
        pattern

   Builder assembles complex object from
    constituent subcomponents
       Client instructs Builder how to create object and
        asks for result
                   Decorator

   Attach additional responsibilities to an object
    dynamically

   Provides a flexible alternative to subclassing
    for extending functionality
               Decorator
                     Example


void doSomething() {

    // Preprocess
    ...

    // Delegate to decorated object
    decorated.doSomething()‫‏‬

    // Postprocess
    ...
}
               Decorator
              Concrete Example

From Java's IO Stream:

   InputStream is =
     new LineNumberInputStream(
     new BufferedInputStream(
     new
      FileInputStream(file)))‫‏‬
                    Facade
   Execute the business logic from one use
    case as one transaction over a single method
    invocation utilising functionality from an
    existing use case.

   Considered as a single interface to features
    of a subsystem specified as a single call to
    the Facade object.

   Facade object exists in addition to the public
    interface it wraps.
Facade
Example
                  Composite
   Represents part-whole hierarchies

   Define a data structure as a linked set of
    nodes

   Client can ignore whether node is a leaf or a
    container
Composite
  Diagram




            From GoF
                         Visitor
   Separates operations from the data
    structures on which they operate

   New operations can be defined with new
    Visitor implementations
       adheres to the Open-Closed Principle

   Traversal order can be specified by:
       the data structure
       the Visitor class
       an external operation (an iterator)
Visitor
Diagram
                     Strategy



   Allows a family of algorithms to be used
    interchangeably by client classes

   Allows for “pluggability”
       Algorithms can be selected at run time
Strategy
 Example
                     Observer
   Defines a one-to-many dependency between
    objects dependent on state through abstract
    interfaces
       Enforces OCP and DIP

       Allows a change to an object's state to be
        propagated to interested objects such that the
        number and types of Observer are immaterial to
        the subject
Observer
 Example
            Further Information
                          Books

   Design Patterns: Elements of Reusable Object-
    Oriented Software
                     Gamma, Helm, Johnson and Vlissides, 1995
                                     (aka Gang of Four book)

   Refactoring: Improving the Design of Existing Code.
                                           Martin Fowler, 1999

   Patterns of Enterprise Application Architecture
                                           Martin Fowler, 2002

   Plenty more in the library
            Further Information
                  Electronic Resources


   Hillside.net Online Pattern Catalog
    (http://hillside.net/patterns/onlinepatterncatalog.htm)

   Refactoring.com

   MartinFowler.com

   Search the Web

				
DOCUMENT INFO