Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Unit 5 Design Patterns: Design by Abstraction. 2 What Are Design Patterns?  Design patterns are: Schematic descriptions of design solutions to recurring.

Similar presentations


Presentation on theme: "1 Unit 5 Design Patterns: Design by Abstraction. 2 What Are Design Patterns?  Design patterns are: Schematic descriptions of design solutions to recurring."— Presentation transcript:

1 1 Unit 5 Design Patterns: Design by Abstraction

2 2 What Are Design Patterns?  Design patterns are: Schematic descriptions of design solutions to recurring problems in software design, and Reusable (i.e., generic), but don’t have to be implemented in the same way.  That is, describe: Design problems that occur repeatedly, and Core solutions to those problems.

3 3 Why Design Patterns?  To capture and document software design knowledge. => helps designers acquire design expertise.  To support reuse in design and boost confidence in software systems.  To provide a common vocabulary for software designers to communicate their designs.

4 4 GoF Patterns Creational StructuralBehavioral Abstract FactoryAdapter Chain of Responsibility Builder BridgeCommand Factory MethodCompositeInterpreter Prototype DecoratorIterator Singleton FaçadeMediator FlyweightMemento ProxyObserver State Strategy Template Method Visitor E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns, Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995.

5 5 Generic Components  Generic components Program components (e.g., classes and packages) that can be extended, adapted, and reused in many different contexts without having to modify the source code Also known as reusable components  Techniques of designing generic components Refactoring Generalizing

6 6 Refactoring  Definition Refactoring means restructuring a program to improve its structure (e.g., to eliminate duplicate code segments) without changing its functionality  Approach Identify code segment that implements the same logic (e.g., duplicate code) Capture the logic in a generic component Restructure by replacing every occurrence of the code segment with a reference to the generic component

7 7 Refactoring Duplication  Why? Hazardous for maintenance Changes must be repeated everywhere Some may be overlooked or forgotten Thus, code segments can easily drift apart  Approach Refactoring by inheritance Refactoring by delegation

8 8 Refactoring by Inheritance class A { void m1() { // … step1(); step2(); step3(); // … } // … } class B { void m2() { // … step1(); step2(); step3(); // … } // … } Sample code: any duplicate?

9 9 Refactored Code class C { void computeAll() { step1(); step2(); step3(); } class A extends C { void m1() { // … computeAll(); // … } // … } class B extends C { void m2() { // … computeAll(); // … } // … }

10 10 Refactoring by Delegation class Helper { void computeAll() { step1(); step2(); step3(); } class A { void m1() { // … h.computeAll(); // … } Helper h; } class B { void m2() { // … h.computeAll(); // … } Helper h; } Q. Compare two approaches of refactoring.

11 11 Strategy Design Pattern Context contextMethod() strategy ConcreteStrategyA algorithm() Strategy alogorithm() ConcreteStrategyB algorithm()  Intent To define a family of algorithms, encapsulate each one, and make them interchangeable strategy.algorithm()

12 e.g.Duck pond simulation game 12 Duck quack() swim() display() MallardDuck display() RedheadDuck display() other Duck

13  Add fly() method  Solution : add fly() in base class  But RubberDuck can’t fly nor quack it can squeak so override quack method & fly method to ‘no fly’  We need to override every method that needs change 13

14  Solution: use of interface flyable & quackable 14 Duck quack() swim() display() MallardDuck fly() quack() display() RedheadDuck fly() quack() display() RubberDuck quack() display() Flyable fly() Quackable quack()

15  No reuse of code as every class has to implement code for the interface  Solution: take what varies & “encapsulate” it so it won’t affect the rest of the code  Later encapsulated part can be extended without affecting rest of the code  All patterns provide a way to let some part of a system vary independently of all other parts 15

16  So pull out the duck behaviors fly & quack  Change the behavior at run time 16 > FlyBehavior fly() FlyWithWings fly() { // implements duck flying } FlyNoWay fly() { // do nothing can’t fly }

17  Simi. interface QuackBehavior is implemented by Quack, Squeak & MuteQuack classes  Other objects can reuse fly & quack behaviors as these are no longer hidden in Duck class  Also we can add new behavior without disturbing existing behaviors 17

18 18 e.g.Duck pond simulation game 18 Duck FlyBehavior flyBehavior QuackBehavior quackBehavior swim() display() performQuack() performFly() setFlyBehavior(FlyBehavior fb) setQuackBehavior(QuackBehavior qb) MallardDuck display() RedheadDuck display() RubberDuck display() Encapsulated Fly behavior Encapsulated Quack behavior

19  Client makes use of an encapsulated family of algorithms for both flying & quacking  Favor composition over inheritance  Duck class is composed of right behavior object 19

20 20 Question  Have we used the Strategy Pattern before?

21 Example : 21

22 State Design Pattern  State pattern is one of the behavioral design pattern.  State design pattern is used when an Object change its behavior based on its internal state.  22

23 e.g. Gumball machine state diagram  Insert quarter  eject quarter turns crank  gumballs=0  gumballs>0   dispense gumball 23 Out of Gumballs No Quarter Gumball sold Has Quarter

24 Java program Public class GumballMachine { final static int SOLD_OUT=0; final static int NO_QUARTER=1; final static int HAS_QUARTER=2; final static int SOLD=3; int state=SOLD_OUT; int count =0; public void insertQuarter() { if(state==HAS_QUARTER) { SOP(“You can’t insert another quarter”); } else if(state==NO_QUARTER) { SOP(“You inserted a quarter”); state= HAS_QUARTER; } 24

25 else if(state==SOLD_OUT) { SOP(“You can’t insert a quarter, the m/c is sold out”); } else if(state==SOLD) { SOP(“please wait we are already giving a gumball”); } public void ejectQuarter() { if(state==HAS_QUARTER) { SOP(“quarter RETURNED”); } ………………………… 25

26  If want to add new state “WINNER”, every method need to be changed as per new state  Instead use interfaces & separate states from code  Map each state to a class  Similar to strategy design pattern 26

27 27 > State insertQuarter() ejectQuarter() turnCrank() dispense() SoldState insertQuarter() ejectQuarter() turnCrank() dispense() SoldOutState insertQuarter() ejectQuarter() turnCrank() dispense() NoQuarterState insertQuarter() ejectQuarter() turnCrank() dispense() HasQuarterState insertQuarter() ejectQuarter() turnCrank() dispense()

28  If you are in NO_QUARTER state & you invoked 1.inserQuarter() method, set gumballMachinneState=HAS_QuarterState  2. ejectQuarter() SOP(“u havent inserted quarter”)  3. turnCrank() SOP(“There is no quarter”)  4. dispense() SOP(“u to pay first”) 28

29 e.g. TV Remote Suppose we want to implement a TV Remote with a simple button to perform action, if the State is ON, it will turn on the TV and if state is OFF, it will turn off the TV. State Interface First of all we will create State interface that will define the method that should be implemented by different concrete states and context class. State.java package com.journaldev.design.state; public interface State { public void doAction(); } Concrete State Implementations In our example, we can have two states – one for turning TV on and another to turn it off. So we will create two concrete state implementations for these behaviors. 29

30 Context Implementation TVContext.java public class TVContext implements State { private State tvState; public void setState(State state) { this.tvState=state; } public State getState() { return this.tvState; } @Override public void doAction() { this.tvState.doAction(); } } Notice that Context also implements State and keep a reference of its current state and forwards the request to the state implementation. 30

31 TVStartState.java public class TVStartState implements State { @Override public void doAction() { System.out.println("TV is turned ON"); } } TVStopState.java package com.journaldev.design.state; public class TVStopState implements State { @Override public void doAction() { System.out.println("TV is turned OFF"); } Now we are ready to implement our Context object that will change its behavior based on its internal state. 31

32 Test Program Now let’s write a simple program to test our implementation of TV Remote using State pattern. TVRemote.java public class TVRemote { public static void main(String[] args) { TVContext context = new TVContext(); State tvStartState = new TVStartState(); State tvStopState = new TVStopState(); context.setState(tvStartState); context.doAction(); context.setState(tvStopState); context.doAction(); } } Output of above program is same as the basic implementation of TV Remote without using any pattern. The benefits of using State pattern to implement polymorphic behavior is clearly visible, the chances of error are less and its very easy to add more states for additional behavior making it more robust, easily maintainable and flexible. Also State pattern helped in avoiding if-else or switch-case conditional logic in this scenario. 32

33 e.g. of Strategy design pattern For our example, we will try to implement a simple Shopping Cart where we have two payment strategies – using Credit Card or using PayPal. First of all we will create the interface for our strategy, in our case to pay the amount passed as argument. PaymentStrategy.java public interface PaymentStrategy { public void pay(int amount); } Now we will have to create concrete implementations of algorithms for payment using credit/debit card or through paypal. 33

34 PaypalStrategy.java public class PaypalStrategy implements PaymentStrategy { private String emailId; private String password; public PaypalStrategy(String email, String pwd){ this.emailId=email; this.password=pwd; } @Override public void pay(int amount) { System.out.println(amount + " paid using Paypal."); } } Now our algorithms are ready and we can implement Shopping Cart and payment method will require input as Payment strategy. 34

35 Item.java package com.journaldev.design.strategy; public class Item { private String upcCode; private int price; public Item(String upc, int cost){ this.upcCode=upc; this.price=cost; } public String getUpcCode() { return upcCode; } public int getPrice() { return price; } } 35

36 ShoppingCart.java package com.journaldev.design.strategy; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; public class ShoppingCart { //List of items List items; public ShoppingCart(){ this.items=new ArrayList (); } 36

37 public void addItem(Item item){ this.items.add(item); } public void removeItem(Item item){ this.items.remove(item); } public int calculateTotal(){ int sum = 0; for(Item item : items){ sum += item.getPrice(); } return sum; } public void pay(PaymentStrategy paymentMethod){ int amount = calculateTotal(); paymentMethod.pay(amount); } 37

38 Notice that payment method of shopping cart requires payment algorithm as argument and doesn’t store it anywhere as instance variable. Let’s test our setup with a simple program. ShoppingCartTest.java shoppingCartTest.java package com.journaldev.design.strategy; public class ShoppingCartTest { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); Item item1 = new Item("1234",10); Item item2 = new Item("5678",40); 38

39 cart.addItem(item1); cart.addItem(item2); //pay by paypal cart.pay(new PaypalStrategy("myemail@example.com", "mypwd")); //pay by credit card cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15")); } package com.journaldev.design.strategy; public class CreditCardStrategy implements PaymentStrategy { private String name; private String cardNumber; private String cvv; private String dateOfExpiry; public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){ this.name=nm; this.cardNumber=ccNum; this.cvv=cvv; this.dateOfExpiry=expiryDate; } @Override public void pay(int amount) { System.out.println(amount +" paid with credit/debit card"); } } Output of above program is: 1 2 50 paid using Paypal. 50 paid with credit/debit card 39

40 Problems Strategy D P 1. Different types of fonts should be decided at run time 2. On college web site, display separate map of every department as the user selects the department. Dpt: IT,Comp, Mech, electrical, E-TC etc. 3. Racing Game: choose car/ bike of different types at run time. 4. Insurance policies are chosen at run time 40

41 Problems State D P  Draw different states of a PC & its state diagram. Design using State D P  State of a student is defined as regular, defaulter, YD, ATKT, new admission, direct admission, pass-out etc. Draw a state diagram & design using State D P  Car states: Draw a state diagram & design using State D P 41

42 Observer Design Pattern Also Known As: Dependents, Publish-Subscribe, and confusingly, Model-View

43 Introduction to Observer  Observer defines a one-to-many or many-to- many dependency between objects.  When the state of one object changes, then all the other objects that are dependent on that object are updated automatically.  Used for event handling where consistency between objects is necessary

44 General Example  Suppose you have some data that can be displayed by a table, a bar graph or a pie chart.  Changes to the underlying data should be reflected in all three of the displays  This is where the Observer Design Pattern comes in handy.

45 Motivation for Using  Maintaining consistency between related objects is necessary when a system contains a collection of cooperating classes  This consistency shouldn’t be accomplished through tightly coupling the classes since this reduces the reusability of those tightly coupled classes.  Needs to be scalable. There should also be no limit on the number of objects that depend on one or more other objects.

46 You are coding an app in which a weather station updates three objects, one that displays current conditions, one that calcs statistics over time (up to date), and one that makes a forecast. Here is the obvious approach: public class WeatherData { [declarations and getters/setters omitted] public void measurements changed(){ float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionsDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); } Freeman, Freeman, Sierra, and Bates, Head First Design Patterns,O’Reilly 2004 Example of the Problem:

47 public void measurementsChanged(){ float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionsDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); } Problems: 1. Area that is likely to change is mixed with area that is not likely to change 2. update() calls are coded to concrete objects, not types 3. Need to change code if the subscribers change Observer addresses these problems Problems With The Obvious Approach

48 Three Major Aspects of Observer 1.The Subject, which is the object being observed 2. The Observer, which observes a Subject 3.Relationship between 1 and 2: attach/detach (or subscribe / unsubscribe) and update

49 Generalized Structure

50 Generalized Structure (cont.) Subject ▫ Interface for ConcreteSubjects ▫ Requires implementations to provide at least the following methods:  subscribe / attach  unsubscribe / detach  notify all observers of state changes ConcreteSubject ▫ Implements the Subject interface ▫ Maintains direct or indirect references to one or more ConcreteObservers ▫ Keeps track of its own state ▫ When its state changes it sends a notification to all of its Observers by calling their update() methods

51 Generalized Structure (cont.)  Observer Interface for ConcreteObserver objects Requires an update method  ConcreteObserver This is the actual object that is observing the state of the ConcreteSubject. The state that it maintains should always be consistent with the state of its Subject. Implements update() method.

52

53 Two Ways to Implement Updates The Push Model ▫ Subject sends all of the necessary information about any of its changes to all the Observers. ▫ Pushes information to the Observer as parameter with the update() method. ▫ Requires assumptions about what the Observers need to know. ▫ May need to allow for subscription to relevant changes only, but this adds complexity The Pull Model ▫ The Subject sends an indication to the Observer that a change has occurred. ▫ Observers use public methods of Subject to query information they want ▫ It is up to the Observer to pull all of the necessary information from the Subject in order to effect any relevant changes. ▫ Subject requires fewer assumptions about what the observers want to know

54 General Implementation  Subjects can track Observers through ArrayLists or other data structures.  Observers can track multiple Subjects and get different data from each.  Pull model uses an update method that takes a reference to Subject as a parameter.  The Subject should trigger updates when its state changes.

55 General Implementation Methods that change state may call a stateChanged() method: public void notifyObservers(){ for(Observer o: observers) o.update(); } public void stateChanged(){ // do other things notifyObservers(); // do whatever else still needs doing } public void setMeasurements(arguments….) { // set instance variables first stateChanged(); }

56 Simple Example: Swing Button With Listeners  Swing JButtons are Subjects; Listeners are Observers  JButton extends AbstractButton, an abstract class that requires methods to add and remove listeners, as well as several types of notify() methods  ActionListener requires that implementers have actionPerformed() method (update())  Can add as many listeners as you like to JButton, as long as they implement ActionListener

57 Familiar Example: Swing Button With Listeners public class SwingObserverExample{ Jframe frame; [stuff omitted] public void go() { frame = new JFrame(); JButton button = new JButton("Should I do it?"); button.addActionListener(new AngelListener()); button.addActionListener(new DevilListener()); frame.getContentPane().add(BorderLayout.CENTER, button); [frame property code omitted] } // using inner classes in this very simple example class AngelListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Don't do it"); } class DevilListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Come on, do it!"); } When we click the button, both listeners are notified and take action. Freeman, Freeman, Sierra, and Bates, Head First Design Patterns,O’Reilly 2004, p. 73

58 Implementation in Java  Java has built-in support for Observer  java.util.Observable class can be extended by a Subject  java.util.Observer interface can be implemented by a class that wants to observe a Subject

59 UML Diagram for Observable/Observer Classes

60 Methods in java.util.Observable Observable() ▫ Creates an Observable object (Subject) with no Observers initially setChanged() ▫ Indicates that this Subject has changed in some way. hasChanged() ▫ Returns True if the setChanged() method has been called more recently than the clearChanged() method. Returns False if otherwise. clearChanged() ▫ Indicates that this object is done notifying all of its observers of its most recent changes. It is called automatically by notifyObservers() method countObservers() ▫ Returns the number of objects that are Observing this Subject.

61 Methods in java.util.Observable (cont.)  addObserver(Observer o) Adds the passed Observer object to the list of Observers kept by the Subject  deleteObserver(Observer o) / deleteObservers() Removes the passed Observer object or all of the Observer objects respectively from the list of Observers kept by the Subject

62 Methods in java.util.Observable (cont.)  notifyObservers(Object arg) / notifyObservers() If this Subject has changed, this method notifies all of its Observers and then calls the clearChanged() method. When given an arg as a parameter in the function call, the Observer knows which attribute of the Subject has changed otherwise the Observer can be notified without specifying an arg.

63 Methods in java.util.Observer  update(Observable o, Object arg) Called when the Subject has changed. o is the Subject in question, and arg is an argument that can be passed to tell the Observer which attribute of the Subject has changed.

64 Limitations of Built-In Implementation (Java)  Observable is a class, not an interface Can’t add its behavior to a concrete class that subclasses something else. Since there is no Observable interface, you can’t create an impl that works with Observer but doesn’t subclass Observable.  Can’t compose another class that has an Observable since setChanged() is protected

65 Questions on Observer Pattern

66 Benefits of the Observer Pattern  Minimal coupling between the Subject and Observer Objects  Many Observers can be added to a Subject without having to modify the Subject.  Reuse of Subjects without needing to also reuse any of their Observers. The opposite also holds true.  The only thing a Subject needs to keep track of is its list of Observers.  The Subject does not need to know the concrete classes of its Observers, only that each one implements the Observer interface

67 Trouble Spots o Cascading notifications if Observers update their own clients or if they can also make changes to the Subject o Repeated notifications when sequences of changes occur. o “Dangling references” to Subjects or Observers when either type are manually deleted in non-garbage collected environments. Need to notify Observers when Subjects are deleted and vice-versa. o Subject state must be self-consistent before calling notify(), especially with pull model. o Careful not to push irrelevant information on observers with push model. o If update() fails, the Observer won’t know that it missed potentially important information

68 ADAPTER PATTERN Winter 2010

69 Intent  Convert the interface of a class into another interface clients expect.  Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.  Wrap an existing class with a new interface.  Also Known As -> Wrapper slide 69

70 Motivation  Sometimes a toolkit or class library can not be used because its interface is incompatible with the interface required by an application  We can not change the library interface, since we may not have its source code  Even if we did have the source code, we probably should not change the library for each domain-specific application slide 70

71 Motivation  Example: slide 71

72 Participants  Target (shape) defines the domain-specific interface that Client uses.  Adapter (TextShape) adapts the interface Adaptee to the Target interface.  Adaptee (TextView) defines an existing interface that needs adapting.  Client (DrawingEditor) collaborates with objects conforming to the Target interface. slide 72

73 Structure  A class adapter uses multiple inheritance to adapt one interface to another: slide 73

74 Structure  An object adapter relies on object composition: slide 74

75 Collaboration slide 75

76 Applicability Use the Adapter pattern when  You want to use an existing class, and its interface does not match the one you need  You want to create a reusable class that cooperates with unrelated classes with incompatible interfaces slide 76

77 Consequences  Object adapter  Adapter can service many different Adaptees  May require the creation of Adaptee subclasses and referencing those objects slide 77

78 Class adapter  Concrete Adapter class  Unknown Adaptee subclasses might cause problem  Overloads Adaptee behavior  Introduces only one object 78

79 Implementation  How much adapting should be done? Simple interface conversion that just changes operation names and order of arguments Totally different set of operations  Does the adapter provide two-way transparency? A two-way adapter supports both the Target and the Adaptee interface. It allows an adapted object (Adapter) to appear as an Adaptee object or a Target object slide 79

80 Example 1  The classic round pegs and square pegs!  Here's the SquarePeg class: /** * The SquarePeg class. * This is the Target class. */ public class SquarePeg { public void insert(String str) { System.out.println("SquarePeg insert(): " + str); } 80

81 Example 1 (continued)  And the RoundPeg class: /** * The RoundPeg class. * This is the Adaptee class. */ public class RoundPeg { public void insertIntoHole(String msg) { System.out.println("RoundPeg insertIntoHole(): " + msg); } If a client only understands the SquarePeg interface for inserting pegs using the insert() method, how can it insert round pegs? A peg adapter! 81

82 Example 1 (continued)  Here is the PegAdapter class: /** * The PegAdapter class. * This is the Adapter class. * It adapts a RoundPeg to a SquarePeg. * Its interface is that of a SquarePeg. */ public class PegAdapter extends SquarePeg { private RoundPeg roundPeg; public PegAdapter(RoundPeg peg) {this.roundPeg = peg;} public void insert(String str) {roundPeg.insertIntoHole(str);} } 82

83 Example 1 (continued)  Typical client program: // Test program for Pegs. public class TestPegs { public static void main(String args[]) { // Create some pegs. RoundPeg roundPeg = new RoundPeg(); SquarePeg squarePeg = new SquarePeg(); // Do an insert using the square peg. squarePeg.insert("Inserting square peg..."); 83

84 Example 1 (continued) // Now we'd like to do an insert using the round peg. // But this client only understands the insert() // method of pegs, not a insertIntoHole() method. // The solution: create an adapter that adapts // a square peg to a round peg! PegAdapter adapter = new PegAdapter(roundPeg); adapter.insert("Inserting round peg..."); }  Client program output: SquarePeg insert(): Inserting square peg... RoundPeg insertIntoHole(): Inserting round peg... 84

85 Example 2  Consider that we have a third party library that provides sorting functionality through it's NumberSorter class. This is our Adaptee /* * This is our adaptee, a third party implementation of a * number sorter that deals with Lists, not arrays. */ public class NumberSorter { public List sort(List numbers) { //sort and return return new ArrayList (); } slide 85

86 Example 2 (continued)  Our Client deals with primitive arrays rather than Lists. For the sake of this example, lets say we can't change the client to use Lists. We've provided a Sorter interface that expects the client input. This is our target. //this is our Target interface public interface Sorter { public int[] sort(int[] numbers); } slide 86

87 Example 2 (continued)  Finally, the SortListAdapter implements our target interface and deals with our adaptee, NumberSorter public class SortListAdapter implements Sorter { @Override public int[] sort(int[] numbers) { //convert the array to a List List numberList = new ArrayList (); //call the adapter NumberSorter sorter = new NumberSorter(); numberList = sorter.sort(numberList); //convert the list back to an array and return return sortedNumbers; } slide 87

88 Example 2 (Continued) int[] numbers = new int[]{34, 2, 4, 12, 1}; Sorter sorter = new SortListAdapter(); sorter.sort(numbers); slide 88

89 Example 3  Notice in Example 1 that the PegAdapter adapts a RoundPeg to a SquarePeg. The interface for PegAdapter is that of a SquarePeg.  What if we want to have an adapter that acts as a SquarePeg or a RoundPeg? Such an adapter is called a two-way adapter.  One way to implement two-way adapters is to use multiple inheritance, but we can't do this in Java  But we can have our adapter class implement two different Java interfaces! 89

90 Example 3 (continued)  Here are the interfaces for round and square pegs: /** *The IRoundPeg interface. */ public interface IRoundPeg { public void insertIntoHole(String msg); } /** *The ISquarePeg interface. */ public interface ISquarePeg { public void insert(String str); } 90

91 Example 3 (continued)  Here are the new RoundPeg and SquarePeg classes. These are essentially the same as before except they now implement the appropriate interface. // The RoundPeg class. public class RoundPeg implements IRoundPeg { public void insertIntoHole(String msg) { System.out.println("RoundPeg insertIntoHole(): " + msg); } // The SquarePeg class. public class SquarePeg implements ISquarePeg { public void insert(String str) { System.out.println("SquarePeg insert(): " + str); } 91

92 Example 3 (continued)  And here is the new PegAdapter: /** * The PegAdapter class. * This is the two-way adapter class. */ public class PegAdapter implements ISquarePeg, IRoundPeg { private RoundPeg roundPeg; private SquarePeg squarePeg; public PegAdapter(RoundPeg peg) {this.roundPeg = peg;} public PegAdapter(SquarePeg peg) {this.squarePeg = peg;} public void insert(String str) {roundPeg.insertIntoHole(str);} public void insertIntoHole(String msg){squarePeg.insert(msg);} } 92

93 Example 3 (continued)  A client that uses the two-way adapter: // Test program for Pegs. public class TestPegs { public static void main(String args[]) { // Create some pegs. RoundPeg roundPeg = new RoundPeg(); SquarePeg squarePeg = new SquarePeg(); // Do an insert using the square peg. squarePeg.insert("Inserting square peg..."); // Create a two-way adapter and do an insert with it. ISquarePeg roundToSquare = new PegAdapter(roundPeg); roundToSquare.insert("Inserting round peg..."); 93

94 Example 3 (continued) // Do an insert using the round peg. roundPeg.insertIntoHole("Inserting round peg..."); // Create a two-way adapter and do an insert with it. IRoundPeg squareToRound = new PegAdapter(squarePeg); squareToRound.insertIntoHole("Inserting square peg..."); }  Client program output: SquarePeg insert(): Inserting square peg... RoundPeg insertIntoHole(): Inserting round peg... SquarePeg insert(): Inserting square peg... 94

95 Related Patterns  The Bridge pattern shares structure with object adapter, but diverges on intent. Bridge is concerned with separating an object's interface from its implementation while adapter changes the interface of an existing object  The Decorator pattern does not change an object's interface, but it does support recursive composition which adapter does not. In this way, Decorator is more flexible than adapter for dealing with functionality additions slide 95

96  In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system. Object- oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Patterns that imply mutable state may be unsuited for functional programming languages, some patterns can be rendered unnecessary in languages that have built- in support for solving the problem they are trying to solve, and object-oriented patterns are not necessarily suitable for non-object-oriented languages.software engineeringdesign patternsoftware designsourcemachinebest practicesObject- orientedinteractionsclassesobjectsfunctional programming  Design patterns may be viewed as a structured approach to computer programming intermediate between the levels of a programming paradigm and a concrete algorithm.computer programmingprogramming paradigmalgorithm 96

97  Types  Design patterns reside in the domain of modules and interconnections. At a higher level there are architectural patterns which are larger in scope, usually describing an overall pattern followed by an entire system. [1]architectural patterns [1]  There are many types of design patterns, for instance [citation needed] [2]citation needed [2]  Algorithm strategy patterns addressing concerns related to high-level strategies describing how to exploit application characteristics on a computing platform. [clarification needed] Algorithm strategy patternsclarification needed  Computational design patterns addressing concerns related to key computation identification. [clarification needed] Computational design patternsclarification needed  Execution patterns which address issues related to lower-level support of application execution, including strategies for executing streams of tasks and for the definition of building blocks to support task synchronization. Execution patterns  Implementation strategy patterns addressing concerns related to implementing source code to support Implementation strategy patterns program organization, and the common data structures specific to parallel programming.  Structural design patterns addressing concerns related to global structures of applications being developed. Structural design patterns 97

98 Documentation  The documentation for a design pattern describes the context in which the pattern is used, the forces within the context that the pattern seeks to resolve, and the suggested solution. [23] There is no single, standard format for documenting design patterns. Rather, a variety of different formats have been used by different pattern authors. However, according to Martin Fowler, certain pattern forms have become more well-known than others, and consequently become common starting points for new pattern-writing efforts. [24] One example of a commonly used documentation format is the one used by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (collectively known as the "Gang of Four", or GoF for short) in their book Design Patterns. It contains the following sections: [23]Martin Fowler [24]Erich GammaRichard HelmRalph JohnsonJohn Vlissides Design Patterns  Pattern Name and Classification: A descriptive and unique name that helps in identifying and referring to the pattern.  Intent: A description of the goal behind the pattern and the reason for using it.  Also Known As: Other names for the pattern.  Motivation (Forces): A scenario consisting of a problem and a context in which this pattern can be used.  Applicability: Situations in which this pattern is usable; the context for the pattern.  Structure: A graphical representation of the pattern. Class diagrams and Interaction diagrams may be used for this purpose.Class diagramsInteraction diagrams  Participants: A listing of the classes and objects used in the pattern and their roles in the design. 98

99 Documentation CONT…  Collaboration: A description of how classes and objects used in the pattern interact with each other.  Consequences: A description of the results, side effects, and trade offs caused by using the pattern.  Implementation: A description of an implementation of the pattern; the solution part of the pattern.  Sample Code: An illustration of how the pattern can be used in a programming language.  Known Uses: Examples of real usages of the pattern.  Related Patterns: Other patterns that have some relationship with the pattern; discussion of the differences between the pattern and similar patterns. 99


Download ppt "1 Unit 5 Design Patterns: Design by Abstraction. 2 What Are Design Patterns?  Design patterns are: Schematic descriptions of design solutions to recurring."

Similar presentations


Ads by Google