Design Patterns - Mar 24
Design Patterns - Mar 24
• Structural
– These ease the design by identifying a simple way to
realize relationships between entities.
• Behavioral
– These identify common communication patterns
between objects and realize these patterns
• Creational
– These deal with object creation mechanisms, trying to
create objects in a manner suitable to the situation
• And there are others …
The Flyweight Design Pattern
• The intent of this pattern is to use sharing to support
a large number of objects that have part of their
internal state in common where the other part of
state can vary.
• This one is a structural pattern – the structural
relationship between specific and shared state is
what is central in this pattern
• When do we use a flyweight?
– When a class has many instances and they can all be
controlled identically
– Classic example of the Flyweight pattern:
• the representation of a character in a word processor
• Rather than each character having separate glyph objects that
represent the font and formatting data, each character could have a
reference to a flyweight glyph object shared by every instance of the
same character in the document.
• Then the character itself would need only to store it's position in the
document and the reference to the glyph, rather than it's entire
formatting information.
The Flyweight Pattern – How does it Work?
Intrinsic state is
what makes a
given object
unique (the glpyh
for a character)
Extrinsic state is
information that
can be passed in
through
arguments the
character’s
position in the
document)
http://www.oodesign.com/flyweight-pattern.html
http://sourcemaking.com/design_patterns/strategy
The Factory Pattern
• Intent:
– creates objects without exposing the instantiation logic to the client.
– refers to the newly created object through a common interface (i.e. a
pointer to base)
– This one is a creational pattern
How you use it:
• The client needs a product, but
instead of creating it directly using
uses the new operator, it asks the factory
Client
object for a new product, and gives
ask for a new object the info about the type of object it
needs.
<<interface>>
Product • The factory instantiates a new
concrete product and then returns
Factory the newly created product (casted to
Concrete abstract product class) to the client.
Product
creates • The client uses the products as
+createProduct():Product
abstract products without being
aware about their concrete
implementation.
http://www.oodesign.com/factory-pattern.html
The Factory Pattern – How does it Work?
• An example:
– You have a graphical application works with shapes.
– The drawing framework is the client and the shapes are the products.
– All the shapes are derived from an abstract Shape class (or interface) that defines
abstract draw and move operations which must be implemented by the concrete
shapes.
– Suppose that a command is selected from a menu to create a new Circle.
– The drawing framework receives the shape type as a string parameter and it asks the
factory to create a new shape, sending the parameter received from menu.
– The factory creates a new Circle and returns it to the framework, as a pointer to the
base abstract class Shape.
– Then the framework uses the pointer to base without being aware of the concrete
object type.
• New shapes can be added without changing a single line of code in the
framework (the client code that uses the shapes from the factory).
uses
Client
http://www.oodesign.com/factory-pattern.html
When should Factory be Used?
• The Factory pattern allows you to create objects
without being bothered by what the actual class
being created is.
• The benefit is that the client code (calling code) can
just say "give me an object that can do XYZ" without
knowing what is the actual class that can do "XYZ".
• Use Factory when
– a class can't anticipate the exact class of objects it must
create.
– 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 subclass is the delegate.
Let’s put this to use: The Game of Set
• Set is a card game
– The object of the game is to identify a ―Set‖ of 3 cards from
12 cards laid out on a table
– Each card has:
• A Color (red, green, or blue)
• A Symbol (oval, squiggle, or diamond)
• A Number (1, 2, or 3 Symbols)
• Shading (solid, open, or striped)
– A ―Set‖ consists of EITHER
• 3 cards with the condition: each of the features is the same on each
card OR is different on each card
– When a set is found, those cards are removed and
replaced by three new cards from the deck
• The deck is made up of 81 distinct cards
• The game continues until the deck is gone
Some Examples of Sets
• These 3 are a Set
Color
Number
Symbol
Shading
L17 Feb. 24, 2010 – friends and software reuse
How would we design a program to play a
solitaire game of Set?
• What is the basic object we have to deal with?
– The card
• What are the operations that we need to do with
cards?
– Display them on the screen
– Check a collection of 3 of them to see if they form a
Set
• What do we know about the properties (features)
of an individual card?
– There are four features:
• Color, Number, Symbol, Shading
– For a given card, these features do not change
What does this suggest as a class for card?
enum Color = {red, blue, green};
class Card
• We’ll need at least one
{
constructor and a destructor
public:
<some methods here, not sure what yet> • And the card needs to be able to
private: draw itself
Color col;
Num num;
Symbol sym;
Shading shade;
};
• What functionality is critical for the class Card?
– We need to be able to determine if three cards form a set
– This means that we need to be able to check their features for
equality
• Two cards with squiggle symbol need to have their Symbol attributes equal
• Two cards with striped shading need to have their Shading attributes equal, even
if one has 2 striped red ovals and the other has 3 striped green diamonds
– How can we do this?
• One solution: write an equals() method for each attribute
• Problem: this will work, but it is very tedious
There is a simpler
– One equals() method for each of the attributes way to do this
How do design patterns come into play?
class Card
{
public:
Card();
Card (Color c, Num n, Symbol sy, Shading sh);
draw();
private:
Color col;
Num num;
Symbol sym;
Shading shade;
};
void Card::draw()
{
setColor (col); //set the display color to the Color attribute of the Card
for each( location in num)
{
sym.draw (shade);
}
}
Now let’s return to the Shading feature
• What does this feature really DO?
– If the application is a graphical one, it designates the fill color
and texture of the shape, once colored
• If open, the fill is the background color
• If solid, the fill is the display color
• If striped, the fill is a texture of the display color
– If the application is a console application, it has to be something
else!
• Turns out, we can set background color and text color independently
• So if we have a console app, we can let the Shading determine the background
color
• Accomplishing the task of displaying the card by using
the draw method of Symbol as our work horse tool lets
us hide the implementation details
– We make the Shading feature be represented by a base class
Shading with derived classes Solid, Open, and Striped
• This class hierarchy has an abstract method getPaint() that each of the derived
classes overrides to make the concrete class
– We can change the nature of the visual display easily by just
changing the getPaint() methods of the Shading derived
classes!
Factory Pattern
• This is an example of using another design
pattern
– The Factory Pattern
• Remember that this pattern has an object return an instance from a
family of related classes that meet this particular class’s needs
• A factory is an object for creating other objects
• The idea is to define an interface (abstract class) for creating an
object, but let the classes which implement the interface decide
which class to instantiate. The Factory method lets a class defer
instantiation to subclasses
So how do we change colors?
• In Visual Studio, the text color and the background
color can be (somewhat independently) set:
– There are 16 colors, and each has a number:
BLACK = 0, BLUE = 1, GREEN = 2, CYAN = 3, RED = 4
MAGENTA = 5, BROWN = 6, LIGHTGREY = 7,
DARKGREY = 8, LIGHTBLUE = 9, LIGHTGREEN = 10, LIGHTCYAN = 11,
LIGHTRED = 12, LIGHTMAGENTA = 13, YELLOW = 14, WHITE =15
– The color of the text and background is determined using
the following formula:
• colorattribute = foreground + background * 16
• to get red text on yellow use 4 + 14*16 = 228
• light red on yellow would be 12 + 14*16 = 236
– Bottom line is that you can easily write the draw method
for a console application!!