1 / 30

Design Patterns

Design Patterns. SWE 619 Software Construction Fall 2008. Design Patterns. Why should we study patterns? Standard solutions to common problems Provide a vocabulary for programmers Bag of tricks! Essential for every programmer. What is a design pattern?.

thuy
Télécharger la présentation

Design Patterns

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Design Patterns SWE 619 Software Construction Fall 2008

  2. Design Patterns • Why should we study patterns? • Standard solutions to common problems • Provide a vocabulary for programmers • Bag of tricks! • Essential for every programmer

  3. What is a design pattern? • It is a design technique geared to a particular, common problem • Example: suppose you need to limit objects to only single, logicially distinct instances • What does it provide? • Optimization (faster execution, lesser memory storage) • Flexibility (remove dependency) • Easier for clients to use your classes

  4. Downside? • Increased complexity • Patterns are not for free • Contrast better performance and flexibility of use with increased difficulty in implementing/maintaining your code • Judgment call, when to use patterns

  5. Use of substitution principal • Many patterns use subtypes while relying on substitution principal • Assume that subtypes will conform to super type specs • Clients need not know which subtype is being used • Types can be changed during execution without requiring client code to change

  6. Types of patterns • Originally proposed by Erich Gamma et al. in GOF book • Three main types of patterns: • Creational patterns: Factory pattern (PolyGen), Singleton, Prototype etc. • Structural patterns: Flyweight, Bridge, Adaptor, Proxy, Façade etc. • Behavioral patterns: Iterator, Command, Strategy, Template etc. • We’ll look at patterns covered in Liskov 15

  7. Factory Pattern • Hides details of object creation. • Why? • Do not want clients burdened with deciding which object to use. • Client code is based on supertype specs • Easier to replace types • Use a factory method to create objects

  8. Factory method • Is it a constructor? NO • Factory may call a constructor Earlier client code: Poly p = new DensePoly(…); Poly q = new SparsePoly(…); New client code: Poly p = PolyProcs.makePoly(); Poly q = PolyProcs.makePoly(); P Q Client P Factory Q Client

  9. Factory Method Benefits • Eliminates the needs to bind application classes into your code. • Client deals with interfaces instead of specific objects • Client may use any class that implements that interface • Enables subclasses to provide extended versions of an object • creating an object inside a factory is more flexible than creating an object directly in the client.

  10. When to Use • When a class cannot anticipate the class of objects it must create. • When a class wants its subclasses to specify the objects it creates. • Classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclasses is the delegate.

  11. Creation of compatible types • Example: • There are 4 types of objects- SparsePoly, DensePoly, SparseMatrix and DenseMatrix • SparsePoly can only be used with SparseMatrix • DensePoly can only be used with DenseMatrix • How can we restrict client code to only use compatible objects? • Solution: Use related factories (f1, f2) • f1 only creates SPoly and SMatrix and f2 only creates DPoly and DMatrix [Figure 15.3]

  12. Compatible types [fig 15.3] M P Poly Matrix Factory F1 F2 SPoly DPoly SMatrix DMatrix

  13. Other Factory Patterns • Builder • Constructs a collection of objects • Prototype • Provides method to obtain new object of same type as prototype • Differs from clone(), in that objects are typically in an initial state • Iteration • Every Iterator is a factory method • Produces a generator object satisfying Iterator interface

  14. Flyweight Pattern • When • Lots of occurrences, need to be shared • Storage costs are high because of the quantity of objects • The application doesn't depend on object identity. • Naïve approach: create new instance each time • Smarter approach: Create only the first time • Benefit • (Possibly) Less memory usage • (Possibly) Better performance

  15. Liskov example 15.4 public class Word { // Overview: … private static Map map; // maps strings to words public static Word makeWord (String s) // factory //E: returns the word corresponding to s private Word (String s) // private to exclude client //E: Makes this to be the word corr. to s public String mapWord (Context c) //E: Returns the string corr. to this // in the form suitable for context c

  16. 2 variations • Key table is hidden from the user • Client need not know if objects are being shared • Example on previous slide • Key table is visible to clients • When there are other uses for the table • E.g. clients need to iterate over all instances. • Example on next slide

  17. Figure 15.5 public class Ident { // O: … Ident (String s) // package private constructor } public class IdentTable { //O: … public IdentTable() // Note: public constructor //E: makes this empty IdentTable public Ident makeReserved(String s) //Nonstatic Ident factory public Ident makeNonReserved (String s) public Iterator idents() // publicly accessible iterator }

  18. State Pattern • When to use • Change the rep periodically for your data abstraction • E.g.: Liskov’s sets are small initially, so use Vector for rep, but if grow to large sizes, use HashSet for rep • How to handle this composite representation?

  19. LiskovSet example • Rep • Before: Vector els; • Now: Vector els; HashSet h; • One (undesirable) approach: • Insert elements into both these objects – gag! • Another (undesirable) approach: • Declare els as: • Object els; (not Vector els or HashTable els). • Depending upon instance, call the right method.

  20. What’s wrong with this approach? • Ugly! • Programmer is doing the job of runtime system • Need a better approach: State pattern • Define a new interface SetState • Needs all the functionality to manipulate Set • SmallSet and BigSet implement the interface • Rep: SetState els; • Now, dispatching is done by runtime sys 

  21. Figure 15.7 public class Set { //rename LiskovSet private SetState els; private int t1; // threshold for growing private int t2; // threshold for shrinking public Set () { els = new SmallSet(); } // set the thresholds public boolean empy() { return els.size() == 0; } public void insert (Object x) { int sz = els.size(); els.insert(x); if (sz == t1 && els.size() >t1 && !(els instanceOf BigSet) els = new BigSet(els); } // note state switch in context object, eg Set

  22. Fig 15.7 continued public interface SetState { //O: SetState is used to implement LiskovSet; it provides most // of the Set methods. SetState objects are mutable } public class SmallSet implements SetState { // implementation similar to that shown in fig 5.6 } public class BigSet implements SetState { … }

  23. Alternate Approach: Switch State in the State Objects • Subtypes of state type could detect need for change and modify containing object directly. • Implies state object (eg BigState) would need to alter context object rep (eg els in Set) • Not necessarily a desirable dependency if (state too small) // in BigState remove() return new SmallState(…); } else return this;

  24. Bridge Pattern • Consider the Poly hierarchy: • How do I extend Poly? Poly SparsePoly DensePoly Poly Poly SparsePoly DensePoly SparsePoly DensePoly MyPoly MyPoly

  25. What’s wrong? • Two different uses of inheritance • Conflict between them • Solution? • Split the type • Figure 15.8 • Not a state pattern (though rep can be switched) • The architecture splits the hierarchy! • Works for Poly as well as Set

  26. Figure 15.8 Set SetState ExtSet SmallSet BigSet

  27. Strategy and Command Patterns • Allow use of procedures as objects • Strategy is for when using context has an expectation about a procedure • Examples: Adder, Comparator, Filterer • Command expects only an interface • Example: Runnable • Often useful for procedures to be “closures” • A closure prebinds some arguments • Example: Filterer g = new LTFilterer(100);

  28. Adaptor, Proxy, Decorator Patterns • Interposing an object between client and existing object • Example: lookup(String s) method that returns all associated objects • Adaptor: Goal is to provide client-specified API to existing object • Example: lookup() only returns one object • Proxy: No change to API; Goal is control • Example: Registry for lookup() resides across network • Decorator: Enhanced API • Example: add additional reverseLookup(Object obj) method • Example: Bloch’s Instrumented Set wrapper example (p 84)

  29. Publish/Subscribe Patterns • Object of interest called a “subject” • Objects interested in subject are “observers” • Observer Pattern • Subject maintains list of observers • Observers join/leave the list • Pull • Observers notified of change • API for observers to obtain more data • Push • Observers get data with notification

  30. More Publish/Subscribe Patterns • Inserting a mediator decouples subject from observers • Allows details of communication to be separated from both subject and observers • White Board • Decouples the caller from the identity of objects that provide a service. • Posting/Obtaining information • Form of multicast

More Related