patterns04 - structural design patterns
DESCRIPTION
An introduction to structural design patterns in object orientation. Suitable for intermediate to advanced computing students and those studying software engineering.TRANSCRIPT
![Page 1: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/1.jpg)
Structural Design PatternsMichael Heron
![Page 2: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/2.jpg)
Introduction Structural design patterns emphasize
relationships between entities. These can be classes or objects.
They are designed to help deal with the combinatorial complexity of large object oriented programs. These often exhibit behaviours that are
not immediately intuitive.
![Page 3: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/3.jpg)
Structural Patterns Common to the whole philosophy behind structural
patterns is the separation between abstraction and implementation. This is a good guideline for extensible design.
Structural patterns subdivide into two broad subcategories. Class structural patterns
Where the emphasis is on the relationship between classes
Object structural patterns The emphasis is on consistency of interaction and
realization of new functionality.
![Page 4: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/4.jpg)
Façade When a model is especially complex, it can be
useful to add in an additional pattern to help manage the external interface of that model. That pattern is called a façade.
A façade sits between the view/controller and provides a stripped down or simplified interface to complex functionality. There are costs to this though in terms of
coupling and cohesion. A façade is a structural pattern.
![Page 5: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/5.jpg)
Façade A façade provides several benefits
Makes software libraries easier to use by providing helper methods
Makes code more readable Can abstract away from the
implementation details of a complex library or collection of classes.
Can work as a wrapper for poorly designed APIs, or for complex compound relationships between objects.
![Page 6: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/6.jpg)
Façade Examplepublic class FacadeExample { SomeClass one; SomeOtherClass two; SomeKindOfConfigClass three; public SomeOtherClass handleInput (String configInfo) { three = SomeKindOfConfigClass (configInfo) one = new SomeClass (configInfo); two = one.getSomethingOut (); return two; } }
![Page 7: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/7.jpg)
Façade Examplepublic class FacadeExample { public SomeOtherClass handleInput (String configInfo) { return myFacade.doSomeMagic (configInfo); } }
public class Facade { SomeClass one; SomeOtherClass two; SomeKindOfConfigClass three; public SomeOtherClass doSomeMagic (String configInfo) { three = SomeKindOfConfigClass (configInfo) one = new SomeClass (configInfo); two = one.getSomethingOut (); return two; } }
![Page 8: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/8.jpg)
Façade The more code that goes through the façade,
the more powerful it becomes. If just used in one place, it has limited benefit.
Multiple objects can make use of the façade. Greatly increasing the easy of development and
reducing the impact of change. All the user has to know is what needs to go
in, and what comes out. The façade hides the rest
![Page 9: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/9.jpg)
Downsides This comes with a necessary loss of control.
You don’t really know what’s happening internally. Facades are by definition simplified interfaces.
So you may not be able to do Clever Stuff when blocked by one.
Facades increase structural complexity. It’s a class that didn’t exist before.
Facades increase coupling and reduce cohesion. They often have to link everywhere, and the set of
methods they expose often lack consistency
![Page 10: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/10.jpg)
The Adapter The Adapter design pattern is used to
provide compatibility between incompatible programming interfaces. This can be used to provide legacy
support, or consistency between different APIs.
These are also sometimes called wrappers. We have a class that wraps around
another class and presents an external interface.
![Page 11: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/11.jpg)
The Adapter Internally, an adapter can be as simple as
a composite object and a method that handles translations. We can combine this with other design
patterns to get more flexible solutions. For example, a factory for adapters Or adapters that work using the strategy
pattern. It is the combination of design patterns
that has the greatest potential in design.
![Page 12: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/12.jpg)
Simple Exampleabstract class Shape { abstract void drawShape (Graphics g, int x1, int x2, int y1, int y2);}
public class Adapter { private Shape sh;
public void drawShape (int x, int y, int len, int ht, Graphics g) { sh.drawShape (g, x, x+ht, y, y+len); }}
![Page 13: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/13.jpg)
Adapters and Facades What’s the difference between a façade and
an adapter? A façade presents a new simplified API to
external objects. An adapter converts an existing API to a
common standard. The Façade creates the programming interface
for the specific combination of objects. The adapter simply enforces consistency
between incompatible interfaces.
![Page 14: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/14.jpg)
The Flyweight Object oriented programming languages
provide fine-grained control over data and behaviours. But that flexibility comes at a cost.
The Flyweight pattern is used to reduce the memory and instantiation cost when dealing with large numbers of finely-grained objects. It does this by sharing state whenever
possible.
![Page 15: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/15.jpg)
Scenario Imagine a word processor.
They’re pretty flexible. You can store decoration detail on any character in the text.
How is this done? You could represent each character as an object. You could have each character contain its own
font object… … but that’s quite a memory overhead.
It would be much better if instead of holding a large font object, we held only a reference to a font object.
![Page 16: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/16.jpg)
The Flyweight The Flyweight pattern comes in to reduce the state
requirements here. It maintains a cache of previously utilised configurations
or styles. Each character is given a reference to a configuration
object. When a configuration is applied, we check the cache to
see if it exists. If it doesn’t, it creates one and add it to the cache.
The Flyweight dramatically reduces the object footprint. We have thousands of small objects rather than
thousands of large objects.
![Page 17: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/17.jpg)
Before and Afterpublic class MyCharacter { char letter; Font myFont; void applyDecoration (string font, int size); myFont = new Font (font, size); }}
public class MyCharacter { char letter; Font myFont; void applyDecoration (string font, int size); myFont = FlyweightCache.getFont (font, size); }}
![Page 18: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/18.jpg)
Implementing a Flyweight The flyweight patterns makes no
implementation assumptions. A reasonably good way to do it is through a
hash map or other collection. Standard memoization techniques can be
used here. When a request is made, check the cache. If it’s there, return it. If it’s not, create it and put it in the cache and
return the new instance.
![Page 19: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/19.jpg)
Limitations of the Flyweight Pattern Flyweight is only an appropriate design
pattern when object references have no context. As in, it doesn’t matter to what they are
being applied. A font object is a good example.
It doesn’t matter if it’s being applied to a number, a character, or a special symbol.
A customer object is a bad example. Each customer is unique.
![Page 20: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/20.jpg)
The Composite Pattern We often have to manipulate collections of
objects when programming. The composite pattern is designed to simplify this.
Internally, it represents data as a simple list or other collection. Requires the use of polymorphism to assure
structural compatability. Externally it presents an API to add and remove
objects. And also to execute operations on the collection as
a whole.
![Page 21: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/21.jpg)
The Composite Patternpublic class ShapeCollection implements Shape() { ArrayList shapes = new ArrayList(); void addShape (Shape s) { shapes.Add (s); } void removeShape (Shape s) { shapes.Remove (s); } void draw() { foreach (Shape s in shapes) { s.draw(); } } void setColour (Colour c) { foreach (Shape s in shapes) { s.setColour (c); } }}
![Page 22: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/22.jpg)
The Composite Patternpublic MainProgram() { Circle circle = new Circle(); Rectangle rect = new Rectangle(); Triangle tri = new Triangle(); ShapeCollection myCollection = new ShapeCollection(); ShapeCollection overallScene = new ShapeCollection(); myCollection.addShape (circle); myCollection.addShape (rect);
overallScene.addShape (myCollection); overallScene.addShape (tri); myCollection.setColour (Colour.RED); overallScene.draw(); }
![Page 23: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/23.jpg)
Why Use Composite? Sometimes we need to be able to perform
operations on groups of objects as a whole. We may wish to move a group of shapes in a
graphics package as one example. These often exist side by side with more
primitive objects that get manipulated individually.
Having handling code for each of these conditions is bad design.
![Page 24: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/24.jpg)
The Composite The composite allows us to treat
collections and individual objects through one consistent interface. We don’t need to worry about which we are
dealing with at any one time. It works by ensuring that the collection
implements the common interface shared by all its constituent bits. The relationship is recursive if done
correctly.
![Page 25: PATTERNS04 - Structural Design Patterns](https://reader033.vdocuments.us/reader033/viewer/2022052907/558fc91f1a28ab64198b45cb/html5/thumbnails/25.jpg)
Summary Structural patterns are the last of the families of
design patterns we are going to look at. We use an adapter to deal with incompatible APIs. We use a bridge to decouple abstraction from
implementation. Implementation is very similar to strategy, only the
intent is unique. Flyweight patterns are used to reduce processing
and memory overheads. Composites are used to allow recursive and
flexible aggregate manipulation of objects.