Design Patterns Adapter Pattern According to the Gang

  • Slides: 44
Download presentation
Design Patterns

Design Patterns

Adapter Pattern According to the Gang of Four, the intent of the Adapter pattern

Adapter Pattern According to the Gang of Four, the intent of the Adapter pattern is to: Convert the interface of a class into another interface that the clients expect. Adapter lets classes work together that could not otherwise because of incompatible interfaces. Intent: create a new interface

Example • Create classes for points, lines, and squares that have the behavior "display.

Example • Create classes for points, lines, and squares that have the behavior "display. " • The client objects should not have to know whether they actually have a point, a line, or a square. They just want to know that they have one of these shapes. free the client object from knowing details

Another Situation. . . • You have wanted to use a subroutine or a

Another Situation. . . • You have wanted to use a subroutine or a method that some one else has written because it performs some function that you need. • You cannot incorporate the routine directly into your program. • The interface or the way of calling the code is not exactly equivalent to the way that its related objects need to use it.

Coming back to our shapes example … • We want the client objects to

Coming back to our shapes example … • We want the client objects to think we have only shapes. – allows the client objects to deal with all these objects in the same way. – enables to add different kinds of shapes in the future without having to change the clients

How to do this … Use derived classes polymorphically define the interface and then

How to do this … Use derived classes polymorphically define the interface and then implement in derived classes Specify behaviour of the Shapes • Set a shape's location. • Get a Shape's location. • Display a Shape. • Fill a Shape. • Set the color of a Shape. • Undisplay a Shape

Adapter Pattern What if you want to add a new shape Circle? Write a

Adapter Pattern What if you want to add a new shape Circle? Write a new derived class and write all relevant methods

What if I have a relevant class? • Somebody wrote easy. Circles with the

What if I have a relevant class? • Somebody wrote easy. Circles with the following methods: – display. It – fill. It – undisplay. It Cannot use easy. Circles directly – Different names and parameter list – Cannot derive it Adapt it

How to implement? • Derive a new class Circle from Shapes • Circle contains

How to implement? • Derive a new class Circle from Shapes • Circle contains easy. Circles. • Circle passes requests made to the Circle object on through to the easy. Circles object.

Adapter Pattern

Adapter Pattern

Adapter Pattern class Circle extends Shape { private easy. Circle pxc; public Circle ()

Adapter Pattern class Circle extends Shape { private easy. Circle pxc; public Circle () { pxc= new easy. Circle(); } void public display() { pxc. display. It(); } }

Adapter Pattern: Key Features Intent Match an existing object beyond your control to a

Adapter Pattern: Key Features Intent Match an existing object beyond your control to a particular interface. Problem A system has the right data and behavior but the wrong interface. Typically used when you have to make something a derivative of an abstract class. Solution The Adapter provides a wrapper with the desired interface. Participants and collaborators The Adapter adapts the interface of an Adaptee to match that of the Adapter's Target (the class it derives from). This allows the Client to use the Adaptee as if it were a type of Target.

Adapter Pattern: Key Features Consequences The Adapter pattern allows for preexisting objects to fit

Adapter Pattern: Key Features Consequences The Adapter pattern allows for preexisting objects to fit into new class structures without being limited by their interfaces. Implementation Contain the existing class in another class. Have the containing class match the required interface and call the methods of the contained class.

Adapter vs Facade A Client object using another, pre-existing object with the wrong interface.

Adapter vs Facade A Client object using another, pre-existing object with the wrong interface.

Strategy Pattern

Strategy Pattern

Strategy Pattern Several software projects tend to ignore long -term issues such as ease

Strategy Pattern Several software projects tend to ignore long -term issues such as ease of maintenance or ability to change

Design for Change – "Program to an interface, not an implementation. “ – "Favor

Design for Change – "Program to an interface, not an implementation. “ – "Favor object [aggregation] over class inheritance. " – "Consider what should be variable in your design. This approach is the opposite of focusing on the cause of redesign. Instead of considering what might force a change to a design, consider what you want to be able to change without redesign. The focus here is on encapsulating the concept that varies, a theme of many design patterns. "

E-Commerce Example • We consider an order-processing system for an international e-commerce company in

E-Commerce Example • We consider an order-processing system for an international e-commerce company in the United States. • This system must be able to process sales orders in many different countries.

System Features • The functions of Sales. Order include the following: – Allow for

System Features • The functions of Sales. Order include the following: – Allow for filling out the order with a GUI – Handle tax calculations – Process the order, and print a sales receipt

New Requirements New requirements for taxation rules – Copy and paste – Switches or

New Requirements New requirements for taxation rules – Copy and paste – Switches or ifs on a variable specifying the case we have – Inheritance (make a derived class that does it the new way)

What we should do? • Based on the guiding principles: – Find what varies

What we should do? • Based on the guiding principles: – Find what varies and encapsulate it in a class of its own. – Contain this class in another class (favor aggregation).

public class Task. Controller { public void process () { /* this code is

public class Task. Controller { public void process () { /* this code is an emulation of a processing controller … figure out which country you are in*/ Calc. Tax my. Tax; my. Tax= get. Tax. Rules. For. Country(); Sales. Order my. SO= new Sales. Order(); my. SO. process(my. Tax); } private Calc. Tax get. Tax. Rules. For. Country() { /* In real life, get the tax rules based on are in. You may have the logic here have it in a configuration file. Here, USTax so this will compile. */ return new USTax(); } } task country you or you may just return a

public class Sales. Order { public void process (Calc. Tax tax. To. Use) {

public class Sales. Order { public void process (Calc. Tax tax. To. Use) { long item. Number= 0; double price= 0; /* given the tax object to use. . calculate tax */ double tax= tax. To. Use. tax. Amount( item. Number, price); } }

public abstract class Calc. Tax { abstract public double tax. Amount( long item. Sold,

public abstract class Calc. Tax { abstract public double tax. Amount( long item. Sold, double price); } public class Can. Tax extends Calc. Tax { public double tax. Amount( long item. Sold, double price) { /* in real life, figure out tax according to the rules in Canada and return it here, return 0 so this will compile*/ return 0. 0; } }

Advantages • Improves cohesion, aids flexibility • Easier to shift responsibilities

Advantages • Improves cohesion, aids flexibility • Easier to shift responsibilities

Strategy Pattern Intent: Define a family of algorithms, encapsulate each one, and make them

Strategy Pattern Intent: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. Motivation The Strategy pattern is based on a few principles: – Objects have responsibilities. – Different, specific implementations of these responsibilities are manifested through the use of polymorphism. – There is a need to manage several different implementations of what is, conceptually, the same algorithm.

General Strategy Pattern

General Strategy Pattern

Observer Pattern

Observer Pattern

e-Commerce Application New requirement: Take actions for new customers – Send a welcome e-mail

e-Commerce Application New requirement: Take actions for new customers – Send a welcome e-mail to the customer. – Verify the customer's address with the post office.

If we knew in advance. . • Hard Code the behaviour The problem? Requirements

If we knew in advance. . • Hard Code the behaviour The problem? Requirements always change Class Responsibility Customer When a customer is added, this object will make calls to the other objects to have the corresponding actions take place. Welcome. Letter Creates welcome letters for customers that let them know they were added to the system. Addr. Verification This object will verify the address of any customer that asks it to.

The Observer Pattern Intent – the intent of the Observer pattern is to "define

The Observer Pattern Intent – the intent of the Observer pattern is to "define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. [GOF] Simply stated: – handling notification automatically

A Common Pattern It also goes by the names Dependents and Publish-Subscribe Where you

A Common Pattern It also goes by the names Dependents and Publish-Subscribe Where you can find them – the notify process in COM – It is implemented in Java with the Observer interface and the Observable class – In rule-based, expert systems, they are often implemented with daemon rules.

Applying Observable Pattern • Two things are varying – Different kinds of objects There

Applying Observable Pattern • Two things are varying – Different kinds of objects There is a list of objects that need to be notified of a change in state. These objects tend to belong to different classes. – Different interfaces Because they belong to different classes, they tend to have different interfaces.

1. Make the Observers behave in the same way • All observers have the

1. Make the Observers behave in the same way • All observers have the same interface • In C# and Java implement this with an interface • In C++, use inheritance 2. Have the observers register themselves Define two methods in the Subject • attach(Observer) adds the given observer to its list of observers • detach(Observer) removes the given observer from its list of observers 3. Notify the observers when the event occurs 4. Get the information from the subject • Each Observer implements a method called update(). • Subject implements a notify() method that goes through its list of Observers and calls this update() method for each of them The update() method should contain the code to handle the event. You must also add method(s) to the Subject that allow the Observers to get whatever information they need

Back to e-Commerce Example

Back to e-Commerce Example

How things work • The Observers attach themselves to the Customer class when they

How things work • The Observers attach themselves to the Customer class when they are instantiated. • When a new Customer is added, the notify method calls these Observers. • Each Observer calls get. State for information on the newly added Customer to see what it needs to do. Note: Typically, there would be several methods to get the needed information.

Customer Class public class Customer { static private Vector my. Obs; static { my.

Customer Class public class Customer { static private Vector my. Obs; static { my. Obs= new Vector(); } public static void attach(My. Observer o){ my. Obs. add. Element(o); } public static void detach(My. Observer o){ my. Obs. remove(o); } public String get. State () { /* have other methods that will give the required information Here, just return null so this will compile*/ return null; } public void notify. Obs () { /*set arg to something that helps tell the Observers what happened */ for (Enumeration e = my. Obs. elements(); e. has. More. Elements() ; ) { ((My. Observer) e). update(this); } } }

interface My. Observer { void update (Customer my. Cust); } class Addr. Verification implements

interface My. Observer { void update (Customer my. Cust); } class Addr. Verification implements My. Observer { public Addr. Verification () { } public void update ( Customer my. Cust) { /* do Address verification stuff here can get more information about customer in question by using my. Cust*/ } } //end of class Addr. Verification

class Welcome. Letter implements My. Observer { public Welcome. Letter () { } public

class Welcome. Letter implements My. Observer { public Welcome. Letter () { } public void update (Customer my. Cust) { /*do Welcome Letter stuff // here can get more information about customer // in question by using my. Cust */ } } //end of class Welcome. Letter

Add new functionality …

Add new functionality …

Key Features Intent Define a one-to-many dependency between objects so that when one object

Key Features Intent Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Problem You need to notify a varying list of objects that an event has occurred. Solution Observers delegate the responsibility for monitoring for an event to a central object: the Subject.

Participants and collaborators The Subject knows its Observers because the Observers register with it.

Participants and collaborators The Subject knows its Observers because the Observers register with it. The Subject must notify the Observers when the event in question occurs. The Observers are responsible both for registering with the Subject and for getting the information from the Subject when notified. Consequences Subjects may tell Observers about events they do not need to know if some Observers are interested in only a subset of events. Extra communication may be required if Subjects notify Observers which then go back and request additional information. Implementation Have objects (Observers) that want to know when an event happens attach themselves to another object (Subject) that is watching for the event to occur or that triggers the event itself. When the event occurs, the Subject tells the Observers that it has occurred. The Adapter pattern is sometimes needed to be able to implement the Observer interface for all of the Observer-type objects.