• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
cs.nyu.edu
 

cs.nyu.edu

on

  • 852 views

 

Statistics

Views

Total Views
852
Views on SlideShare
852
Embed Views
0

Actions

Likes
0
Downloads
11
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • By using an abstract class rather than a concrete class in all of your derived classes you have more freedom to implement these methods as most suits your purposes. While many beginning OO programmers use inheritance to solve every problem, as you begin to write more elaborate programs, the merits of object composition become apparent. Your new object can have the interface that is best for what you want to accomplish without having all the methods of the parent classes.
  • Inheritance is a generalization technique, in which the behavior of a superclass is shared by all its subclasses. Sometimes it is misused as an implementation technique. Question: Can you give me an example for unwanted behavior?

cs.nyu.edu cs.nyu.edu Presentation Transcript

  • Software Engineering
    • October 17, 2001
    • Design Patterns
    • Joseph Conron
    • Computer Science Department
    • New York University
    • [email_address]
  • How to Become a Chess Master
    • First learn rules and physical requirements
      • e.g., names of pieces, legal movements, chess board geometry and orientation, etc.
    • Then learn principles
      • e.g., relative value of certain pieces, strategic value of center squares, power of a threat, etc.
    • However, to become a master of chess, one must study the games of other masters
      • These games contain patterns that must be understood, memorized, and applied repeatedly
    • There are hundreds of these patterns
  • How to Become a Software Design Master
    • First learn the rules
      • e.g., the algorithms, data structures and languages of software
    • Then learn principles
      • e.g., structured programming, modular programming, object oriented programming, etc.
    • However, to truly master software design, one must study the designs of other masters
      • These designs contain patterns that must be understood, memorized, and applied repeatedly
    • There are hundreds of these patterns
  • A Design Pattern:
    • … describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use the this solution a million times over, without ever doing it the same twice
    • … captures design knowledge
      • Higher level than classes or data structures (link lists,binary trees...)
      • Lower level than application frameworks
    • … is a modifiable design
  • What makes a design modifiable?
    • Low coupling and high coherence
    • Clear dependencies
    • Explicit assumptions
    • How do design patterns help?
    • They are generalized from existing systems
    • They provide a shared vocabulary to designers
    • They provide examples of modifiable designs
      • Abstract classes
      • Delegation
  • Principles from Design Patterns
    • Program to an interface and not to an implementation.
      • define the top of any class hierarchy with an abstract class which implements no methods, but simply defines the methods that class will support.
    • Favor object composition over inheritance.
      • Don’t rely only on class inheritance to add new functionality.
  • Reuse
    • Main goal:
      • Reuse knowledge from previous experience to current problem
      • Reuse functionality already available
    • Two ways to get new functionality:
      • Inheritance (also called White-box Reuse)
        • New functionality is obtained by inheritance .
      • Composition (also called Black Box Reuse)
        • New functionality is obtained by aggregation
        • The new object with more functionality is an aggregation of existing components
  • Implementation Inheritance vs Interface Inheritance
    • Implementation inheritance
      • Also called class inheritance
      • Goal: Extend an applications’ functionality by reusing functionality in parent class
      • Inherit from an existing class with some or all operations already implemented
    • Interface inheritance
      • Also called subtyping
      • Inherit from an abstract class with all operations specified, but not yet implemented
  • Implementation Inheritance
    • A very similar class is already implemented that does almost the same as the desired class implementation.
    • Problem with implementation inheritance:
      • Some of the inherited operations might exhibit unwanted behavior. What happens if the Stack user calls Remove() instead of Pop()?
    • Example: I have a List class, I need a Stack class. How about subclassing the Stack class from the List class and providing three methods, Push() and Pop(), Top() ?
    Add () Remove() List Push () Pop() Stack Top() “ Already implemented”
  • Interface inheritance vs. implementation inheritance
    • Interface inheritance
      • separates interface and implementation
      • implementations may be transparently substituted
      • decreases coupling
    • Implementation inheritance (“class inheritance”)
      • introduces dependencies among an ancestor and its descendents (inherited state)
      • mixes interface specification and implementation
      • can be achieved with delegation instead
    • The Design Patterns book shows how to avoid implementation inheritance with a mix of interface inheritance and delegation
  • Composition
    • New object is formed by composing it from existing objects
    • Requires new objects have well-defined interfaces
    • Since objects are accessed solely through their interfaces, encapsulation is preserved:
      • Objects can be replaced at runtime rather than compile time
      • Fewer implementation dependencies
  • Delegation
    • Delegation is a way of making composition (for example aggregation) as powerful for reuse as inheritance
    • In Delegation two objects are involved in handling a request
      • A receiving object delegates operations to its delegate.
      • The developer can make sure that the receiving object does not allow the client to misuse the delegate object
    Client Receiver Delegate Delegates to calls
  • Delegation or Inheritance?
    • Delegation
      • Pro:
        • Flexibility: Any object can be replaced at run time by another one (as long as it has the same type)
      • Con:
        • Inefficiency: Objects are encapsulated.
    • Inheritance
      • Pro:
        • Straightforward to use
        • Supported by many programming languages
        • Easy to implement new functionality
      • Con:
        • Inheritance exposes a subclass to the details of its parent class
        • Any change in the parent class implementation forces the subclass to change (which requires recompilation of both)
  • Delegation instead of Inheritance
    • Delegation: Catching an operation and sending it to another object.
    +Add() +Remove() List Stack +Push() +Pop() +Top() Stack Add() Remove() List +Push() +Pop() +Top()
    • Many design patterns use a combination of inheritance and delegation
  • On to the Patterns!
    • A Design Pattern has 4 basic parts:
      • Name
      • Problem
      • Solution
      • Consequences and trade-offs of application
    • A Design Pattern is language and implementation independent
  • Design Patterns: the basic 23 patterns from GOF Scope: domain over which a pattern applies Purpose: reflects what a pattern does
  • A Pattern Taxonomy
    • Creational Patterns
      • Abstract the instantiation process.
      • Make a system independent from the way its objects are created, composed and represented.
      • Example: Factory
    • Structural Patterns
      • Adapters, Bridges, Facades, and Proxies are variations on a single theme:
        • They reduce the coupling between two or more classes
        • They introduce an abstract class to enable future extensions
        • Encapsulate complex structures
    • Behavioral Patterns
      • Concerned with algorithms and the assignment of responsibilies between objects: Who does what?
      • Characterize complex control flow that is difficult to follow at runtime.
      • Example: Observer, Iterator, Command
  • Factory Pattern (Creational)
    • Factory pattern is one that returns an instance of one of several possible classes depending on the data provided to it.
    • Usually all of the classes it returns have a common parent class and common methods.
    • Each factory produced class performs a task differently and is optimized for different kinds of data.
  • Factory Pattern
  • When to Use a Factory Pattern
    • You should consider using a Factory pattern when
      • A class can’t anticipate which kind of class of objects it must create.
      • A class uses its subclasses to specify which objects it creates.
      • You want to localize the knowledge of which class gets created.
    • There are several similar variations on the factory pattern to recognize.
      • The base class is abstract and the pattern must return a complete working class.
      • The base class contains default methods and is only sub-classed for cases where the default methods are insufficient.
      • Parameters are passed to the factory telling it which of several class types to return. In this case the classes may share the same method names but may do something quite different.
  • Adapter Pattern (Structural)
    • “ Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces
    • Used to provide a new interface to existing legacy components (Interface engineering, reengineering).
    • Also known as a wrapper
    • Two adapter patterns:
      • Class adapter:
        • Uses multiple inheritance to adapt one interface to another
      • Object adapter:
        • Uses single inheritance and delegation
    • Delegation is used to bind an Adapter and an Adaptee
    • Interface inheritance is use to specify the interface of the Adapter class.
    • Target and Adaptee (usually called legacy system) pre-exist the Adapter.
    • Target may be realized as an interface in Java.
    Adapter pattern Client Target Request() Adaptee ExistingRequest() adaptee Adapter Request()
  • Adapter pattern example
    • public class ServicesEnumeration
    • implements Enumeration {
    • public boolean hasMoreElements () {
    • return this.currentServiceIdx <= adaptee.numServices();
    • }
    • public Object nextElement () {
    • if (!this.hasMoreElements()) {
    • throw new NoSuchElementException();
    • }
    • return adaptee.getService(this.currentSerrviceIdx++);
    • }
    Client Enumeration hasMoreElements() nextElement() RegisteredServices numServices(); getService(int num); adaptee ServicesEnumeration hasMoreElements() nextElement()
  • Bridge Pattern (Structural)
    • Use a bridge to “decouple an abstraction from its implementation so that the two can vary independently”. (From [Gamma et al 1995])
    • Also know as a Handle/Body pattern.
    • Allows different implementations of an interface to be decided upon dynamically.
  • Bridge pattern (UML) RefinedAbstraction Implementor imp provides Abstraction Concrete ImplementorA Concrete ImplementorB Subsystem
  • Bridge Pattern Example ODBC Implementation ODBC imp Abstracting database vendors: removing the dependency from database vendors from the systems provides more flexibility . Oracle ODBC Driver DB2 ODBC Driver Informix ODBC Driver
  • Using a Bridge
    • The bridge pattern is used to provide multiple implementations under the same interface.
    • The Bridge pattern is intended to keep the interface to your client program constant while allowing you to change the actual kind of class you display or use. This can SAVE you from recompiling a complicated set of user interface modules, and only require that you recompile the bridge itself and the actual end display class.
    • You can extend the implementation class and the bridge class separately, and usually without much interaction with each other.
  • Proxy Pattern (Structural)
    • What is expensive?
      • Object Creation
      • Object Initialization
    • Defer object creation and object initialization to the time you need the object
    • Proxy pattern:
      • Reduces the cost of accessing objects
      • Uses another object (“the proxy”) that acts as a stand-in for the real object
      • The proxy creates the real object only if the user asks for it
  • Proxy pattern
    • Interface inheritance is used to specify the interface shared by Proxy and RealSubject.
    • Delegation is used to catch and forward any accesses to the RealSubject (if desired)
    • Proxy patterns can be used for lazy evaluation and for remote invocation.
    • Proxy patterns can be implemented with a Java interface.
    Subject Request() RealSubject Request() Proxy Request() realSubject
  • Proxy Example
    • Problem: provide access protection to stock/bond portfolio
    • To access portfolio, Broker can use PortfolioProxy .
    • PortfolioProxy first checks with the if the invoking Broker has legitimate access. Once access has been granted, PortfolioProxy delegates the operation to the actual Portfolio object.
    • One Access association can be used to control access to many Portfolios .
  • Proxy Example (Protection) Portfolio buy() sell() estimateYield() 1 1 * 1 Broker buy() sell() estimateYield() Dynamic access implemented with a protection Proxy . Access isAccessible(op) PortfolioProxy
  • Proxy Applicability
    • Remote Proxy
      • Local representative for an object in a different address space
    • Virtual Proxy
      • Object is too expensive to create or too expensive to download
      • Proxy is a stand-in
    • Protection Proxy
      • Proxy provides access control to the real object
      • Useful when different objects should have different access and viewing rights for the same document.
      • Example: Grade information for a student shared by administrators, teachers and students.
  • Command Pattern (Behavioral)
    • You want to build a user interface
    • You want to provide menus
    • You want to make the user interface reusable across many applications
      • You cannot hardcode the meanings of the menus for the various applications
      • The applications only know what has to be done when a menu is selected.
    • Such a menu can easily be implemented with the Command Pattern
  • Command pattern
    • Client creates a ConcreteCommand and binds it with a Receiver.
    • Client hands the ConcreteCommand over to the Invoker which stores it.
    • The Invoker has the responsibility to do the command (“execute” or “undo”) .
    Command execute() Client Invoker binds Receiver action() ConcreteCommand execute()
  • Menu Example Command execute() Application Menu Item binds Menu * * Document action() Copy execute() Paste execute() Client Invoker: Asks the Command object To carry out the request Concrete Command Receiver
  • Command pattern Applicability
    • “ Encapsulate a request as an object, thereby letting you
      • parameterize clients with different requests,
      • queue or log requests, and
      • support undoable operations.”
    • Uses:
      • Undo queues
      • Database transaction buffering
  • Structuring the objects Menu MoveCommand Rectangle Editor UndoQueue Invoker (Boundary objects) ConcreteCommands (Control objects) Receiver (Entity objects) Triangle Circle
  • Command pattern: typical sequence anEditor newCommand(info) store(MoveCommand1) execute() move(x, y) aUser Drags mouse “ MoveCommand1 ” aRectangle: Rectangle moveCommand undoQueue
  • Observer pattern (Behavioral)
    • “ Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.” (p. 293)
    • Also called “Publish and Subscribe”
    • Uses:
      • Maintaining consistency across redundant state
      • Optimizing batch changes to maintain consistency
  • Observer pattern (continued) 9DesignPatterns2.ppt Observers Subject
  • Observer pattern (continued)
    • The Subject represents the actual state, the Observers represent different views of the state.
    • Observer can be implemented as a Java interface.
    • Subject is a super class (needs to store the observers vector) not an interface.
    observers subject * Observer update() Subject attach(observer) detach(observer) notify() ConcreteSubject getState() setState(newState) subjectState ConcreteObserver update() observerState
  • Sequence diagram for scenario: Change filename to “foo” getState() aListView anInfoView aFile “ foo” update() update() setState(“foo”) notify() Attach() Attach() Subject goes through all its observers and calls update() on them, asking for the new state is decoupled from the notification
  • Animated Sequence diagram getState() aListView anInfoView aFile notify() Attach() Attach() “ foo” setState(“foo”) update() update()
  • Observer pattern implementation in Java
    • // import java.util;
    • public class Observable extends Object {
    • public void addObserver(Observer o);
    • public void deleteObserver(Observer o);
    • public boolean hasChanged();
    • public void notifyObservers();
    • public void notifyObservers(Object arg);
    • }
    • public abstract interface Observer {
    • public abstract void update(Observable o, Object arg);
    • }
    • public class Subject extends Observable{
    • public void setState(String filename);
    • public string getState();
    • }
  • Strategy Pattern
    • Many different algorithms exists for the same task
    • Examples:
      • Breaking a stream of text into lines
      • Parsing a set of tokens into an abstract syntax tree
      • Sorting a list of customers
    • The different algorithms will be appropriate at different times
      • Rapid prototyping vs delivery of final product
    • We don’t want to support all the algorithms if we don’t need them
    • If we need a new algorithm, we want to add it easily without disturbing the application using the algorithm
  • Strategy Pattern Context ContextInterface() ConcreteStrategyC AlgorithmInterface() Strategy * ConcreteStrategyB AlgorithmInterface() ConcreteStrategyA AlgorithmInterface() Strategy AlgorithmInterface
  • Applying a Strategy Pattern in a Database Application Database Search() Sort() ShellSort Sort(CustomerList) Strategy * QuickSort Sort(CustomerList) BubbleSort Sort(CustomerList) Strategy Sort()
  • Applicability of Strategy Pattern
    • Many related classes differ only in their behavior. Strategy allows to configure a single class with one of many behaviors
    • Different variants of an algorithm are needed that trade-off space against time. All these variants can be implemented as a class hierarchy of algorithms
  • Summary
    • Structural Patterns
      • Focus: How objects are composed to form larger structures
      • Problems solved:
        • Realize new functionality from old functionality,
        • Provide flexibility and extensibility
    • Behavioral Patterns
      • Focus: Algorithms and the assignment of responsibilities to objects
      • Problem solved:
        • Too tight coupling to a particular algorithm
    • Creational Patterns
      • Focus: Creation of complex objects
      • Problems solved:
        • Hide how complex objects are created and put together
  • Conclusion
    • Design patterns
      • Provide solutions to common problems.
      • Lead to extensible models and code.
      • Can be used as is or as examples of interface inheritance and delegation.
      • Apply the same principles to structure and to behavior.
    • Design patterns solve all your software engineering problems