1 / 92

Structural Patterns

Structural Patterns. How classes and objects are composed to form larger structures Structural class patterns : use inheritance to compose interfaces or implementations Structural object patterns: describe ways to compose objects to realize new functionality. Structural Patterns. Adapter

jewele
Download Presentation

Structural 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. Structural Patterns • How classes and objects are composed to form larger structures • Structural class patterns: use inheritance to compose interfaces or implementations • Structural object patterns: describe ways to compose objects to realize new functionality

  2. Structural Patterns • Adapter • Façade • Flyweight • Bridge • Composite • Proxy

  3. US-made laptop in a European country

  4. Structural Patterns - Adapter • 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 • 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

  5. Adapter Pattern The Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces

  6. Structural Patterns - Adapter • TextShape Example: a drawing editor that lets users draw and arrange graphical elements (lines, polygons, text, etc.) into pictures and diagrams. The drawing editor's key abstraction is the graphical object, which has an editable shape and can draw itself. The interface for graphical objects is defined by an abstract class called Shape. The editor defines a subclass of Shape for each kind of graphical object: a LineShape class for lines, a PolygonShape class for polygons, a TextShape class for text editing. • by inheriting Shape's interface and TextView's implementation • by composing a TextView instance within a TextShape and implementing TextShape in terms of TextView's interface

  7. Structural Patterns - Adapter Class Diagram: TextShape Example

  8. Structural Patterns - Adapter Structure: Class Diagram A class adapter uses multiple inheritance to adapt one interface to another: An object adapter relies on object composition:

  9. Structural Patterns - Adapter • Target— defines the domain-specific interface that the client uses. • Client— collaborates with objects conforming to the Target interface. • Adaptee— defines an existing interface that needs adapting. • Adapter— adapts the interface of Adaptee to the Target interface. Participants Collaborations • Clients call operations on an Adapter instance. In turn, the Adapter calls Adaptee operations that carry out the request.

  10. Structural Patterns - Adapter Applicability • 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 or unforeseen classes that don't have compatible interfaces. Implementation Issues • 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

  11. Structural Patterns - Adapter Adapter Pattern 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); } }

  12. Structural Patterns - Adapter • And the RoundPeg class: /** * The RoundPeg class. * This is the Adaptee class. */ public class RoundPeg { public void insertIntoHole(String msg) { System.out.println("RoundPeginsertIntoHole(): " + 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!

  13. Structural Patterns - Adapter • 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);} }

  14. Structural Patterns - Adapter • 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..."); // 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..."); } }

  15. Structural Patterns - Adapter • Client program output: SquarePeg insert(): Inserting square peg... RoundPeg insertIntoHole(): Inserting round peg...

  16. Structural Patterns - Adapter Adapter Pattern Example 2: • 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!

  17. Structural Patterns - Adapter • 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); }

  18. Structural Patterns - Adapter • 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("RoundPeginsertIntoHole(): " + msg); } } // The SquarePeg class. public class SquarePeg implements ISquarePeg { public void insert(String str) { System.out.println("SquarePeg insert(): " + str); } }

  19. Structural Patterns - Adapter • Here is the new PegAdapter class: /** * 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);} }

  20. Structural Patterns - Adapter • 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..."); // 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..."); } }

  21. Structural Patterns - Adapter • Client program output: SquarePeg insert(): Inserting square peg... RoundPeg insertIntoHole(): Inserting round peg... RoundPeg insertIntoHole(): Inserting round peg... SquarePeg insert(): Inserting square peg...

  22. Structural Patterns - Adapter Motivation Example 3: class Shape { public: Shape(); virtual void BoundingBox( Point& bottomLeft, Point& topRight ) const; virtual Manipulator* CreateManipulator() const; }; class TextView { public: TextView(); void GetOrigin(Coord& x, Coord& y) const; void GetExtent(Coord& width, Coord& height) const; virtual bool IsEmpty() const; };

  23. Structural Patterns - Adapter • Multiple Inheritance: • Key to Class Adapter: use one inheritance branch to inherit the interface and another branch to inherit the implementation class TextShape : public Shape, private TextView { public: TextShape(); virtual void BoundingBox( Point& bottomLeft, Point& topRight ) const; virtual bool IsEmpty() const; virtual Manipulator* CreateManipulator() const; };

  24. Structural Patterns - Adapter void TextShape::BoundingBox (Point& bottomLeft, Point& topRight) const { Coord bottom, left, width, height; GetOrigin(bottom, left); GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width); } bool TextShape::IsEmpty () const { return TextView::IsEmpty(); } Manipulator* TextShape::CreateManipulator () const { return new TextManipulator(this); }

  25. Structural Patterns - Adapter • Object adapter: use object composition to combine classes with different interfaces class TextShape : public Shape { public: TextShape(TextView*); virtual void BoundingBox( Point& bottomLeft, Point& topRight ) const; virtual bool IsEmpty() const; virtual Manipulator* CreateManipulator() const; private: TextView* _text; };

  26. Structural Patterns - Adapter TextShape::TextShape (TextView* t) {_text = t;} void TextShape::BoundingBox (Point& bottomLeft, Point& topRight) const { Coord bottom, left, width, height; _text->GetOrigin(bottom, left); _text->GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width); } bool TextShape::IsEmpty () const { return _text->IsEmpty(); } Manipulator* TextShape::CreateManipulator () const { return new TextManipulator(this); }

  27. Structural Patterns - Adapter • Compared with the class adapter case, the object adapter requires a little more effort to write, but it's more flexible. • the object adapter version of TextShape will work equally well with subclasses of TextView—the client simply passes an instance of a TextView subclass to the TextShape constructor

  28. Real World Adapters • Old world Enumerators • New world Enumerators

  29. Home Sweet Home Theater • A DVD player • A projection video system • An automated screen • Surround sound • And even • A popcorn popper

  30. Home Theater

  31. Watching a movie • Turn on the popcorn popper • Start the popper popping • Dim the lights • Put the screen down • Turn the projector on • Set the project input to DVD • Put the projector on wide-screen mode • Turn the sound amplifier on • Set the amplifier to DVD input • Set the amplifier to surround sound • Set the amplifier volumn to medium • Turn the DVD player on • Start the DVD player playing

  32. What if: • The movie is over? • Just want to listen to CD or Radio? • Upgrade your system?

  33. watchMovie()

  34. Structural Patterns - Façade Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use. Intent Applicability • Provides a simple interface to a complex subsystem. • Decouples the details of a subsystem from clients and other subsystems. • Provides a layered approach to subsystems.

  35. Structural Patterns - Façade Class Diagram subsystem Facade

  36. Structural Patterns - Façade Motivation

  37. Structural Patterns - Façade • Façade • Knows which classes are responsible for each request. • Delegates client requests to appropriate objects. • Subsystem classes • Implement subsystem functionality. • Handle work assigned by the Façade object. • Have no knowledge of the façade. Participants Collaborations • Clients communicate with the subsystem sending requests to the Façade. • Reduces the number of classes the client deals with. • Simplifies the subsystem. • Clients do not have to access subsystem objects directly.

  38. Structural Patterns - Façade Consequences Benefits • It hides the implementation of the subsystem from clients, making the subsystem easier to use • It promotes weak coupling between the subsystem and its clients. This allows you to change the classes that comprise the subsystem without affecting the clients. • It reduces compilation dependencies in large software systems • It simplifies porting systems to other platforms, because it's less likely that building one subsystem requires building all others • It does not prevent sophisticated clients from accessing the underlying classes • Note that Facade does not add any functionality, it just simplifies interfaces Liabilities • It does not prevent clients from accessing the underlying classes!

  39. Structural Patterns - Façade An example: Compiler

  40. Structural Patterns - Façade Façade Pattern Tutorial: https://www.youtube.com/watch?v=B1Y8fcYrz5o

  41. Facade Pattern The Facade Pattern provides a unified interface to a set of interfaces in the subsystems. Façade defines a higher-level interface that makes the subsystem easier to use Principle of Least Knowledge—talk only to your immediate friend.

  42. Hints • We should only invoke methods that belong to: • The object itself • Objects passed in as a parameter to the method • Any object the method creates or instantiates • Any components of the object

  43. Bullet Points • When you need to use an existing class and its interface is not the one you need, use an adapter • When you need to simplify and unify a large interface or complex set of interfaces, use a façade • An adapter changes an interface into one a client expects

  44. Bullet Points • A façade decouples a client from a complex subsystem. • Implementing an adapter may require little work or a great deal of work depending on the size and complexity of the target interface • Implementing a façade requires that we compose the façade with its subsystem and use delegation to perform the work of the façade

  45. Bullet Points • There are two forms of the Adapter Pattern: object and class adapters. Class adapters require multiple inheritance • You can implement more than one façade for a subsystem • An adapter wraps an object to change its interface and a façade “wraps” a set of object to simplify.

  46. What if there are too many instances?

  47. Flyweight Pattern

  48. Flyweight Benefits Reduce the number of object instances at runtime, saving memory Centralizes states for many “virtual” objects into a single location

  49. Flyweight Uses and Drawbacks The Flyweight is used when a class has many instances, and they can all be controlled identically A drawback of the Flyweight pattern is that once you’ve implemented it, single, logical instances of the class will not be able to behave independently from the other instances.

  50. Structural Patterns - Flyweight Flyweight Pattern Tutorial: https://www.youtube.com/watch?v=0vV-R2926ss

More Related