0% found this document useful (0 votes)
39 views28 pages

Design Patterns - Mar 24

The document introduces several common design patterns including structural, behavioral, and creational patterns. It then provides more detailed explanations of the Flyweight, Strategy, and Factory patterns. The Flyweight pattern focuses on efficient use of memory by sharing objects. The Strategy pattern defines a family of interchangeable algorithms. The Factory pattern creates objects without exposing instantiation logic.

Uploaded by

Jitendra Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views28 pages

Design Patterns - Mar 24

The document introduces several common design patterns including structural, behavioral, and creational patterns. It then provides more detailed explanations of the Flyweight, Strategy, and Factory patterns. The Flyweight pattern focuses on efficient use of memory by sharing objects. The Strategy pattern defines a family of interchangeable algorithms. The Factory pattern creates objects without exposing instantiation logic.

Uploaded by

Jitendra Patel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Introduction to Design Patterns

• First, what’s a design pattern?


– a general reusable solution to a commonly occurring
problem within a given context in software design
– It’s not a finished design that can be transformed
directly into 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 you must
implement yourself in your application
• Design patterns gained popularity after the book
Design Patterns: Elements of Reusable Object-
Oriented Software was published in 1994 by the
so-called "Gang of Four" (Gamma et al.).
Some Kinds of Design Patterns

• 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

• The Flyweight interface declares methods which flyweight


instances can receive and use extrinsic data.
• The FlyweightFactory is responsible for the creation and
management of the flyweights, ensuring that they are shared
properly. If the desired Flyweight isn't created yet it will create and
return one. Otherwise, it will return one from the current pool of
flyweights. Often it’s an indexer.
• A ConcreteFlyweight object adds capabilities for intrinsic state.
• The Client is your application program
The Strategy Pattern
• Intent:
– Define a family of algorithms, encapsulate each one, and make them
interchangeable.
– Capture the abstraction in an interface, bury implementation details in
derived classes.
– This one is a behavioral pattern – the interface idealizes the behavior

Interface could be:


• an abstract base class
 In this case, we have
dynamic polymorphism
• the method signature
expectations by the client
 In this case, the Interface
entity represents
template code and the
inheritance hierarchy
represents static
polymorphism
http://sourcemaking.com/design_patterns/strategy
The Strategy Pattern – How does it Work?
• Define an interface that is common to all aspects of some behavior
– This could be a pure virtual function in a base class or a template function
with its parameterized signature
• Define algorithms specific to particular instances of that behavior
– These could be concrete functions that implement the base class’s pure
virtual function (or the parameterized code of the template function)
• The client code creates a context in which a specific concrete
algorithm is invoked that is appropriate in the runtime context
– The client code makes use of a pointer to base class to refer to a derived
class object and then the proper binding of concrete method to function call
(or the binding to type of argument) is done at runtime

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

ask for a new object


<<interface>>
Product
Factory
Concrete
Product
creates +createProduct():Product

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

• They all have 2 ovals – so they agree on


Symbol and on Number
• They are all of different Colors
• They are all of different Shading

L17 Feb. 24, 2010 – friends and software reuse


Some Examples of Sets
• These 3 are a Set

• They all have the same Color and the same


Shading
• They are all of different Symbols
• They are all of different Numbers

L17 Feb. 24, 2010 – friends and software reuse


What would a typical game table look like?

Where are
the sets?

 

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;
};

• We need to look at these objects that represent the


4 attributes each Card has
Color
• Each card is assigned a Color
• This color is used for two things:
– To draw the symbol in a particular color
– To do the fill in the symbol (if solid or striped, it should be
of that color, assuming a ―graphical‖ world)
• Our base assumptions are that Color will have one
of three values:
– Red
– Blue
– Green
• So we make a class Color with an attribute that
indicates the color and with methods that will let us
construct a Color object, set its data value, and
retrieve its data value
The class Color
class Color Color::Color()
{ {
public: col = 15; // default color is white
Color(); }
Color (int c);
int get_color();
Color::Color (int c)
void set_color(int c);
bool operator == (Color &c) {
private: col = (c % 16); // color is between 0 and 15
int col; }
}
int Color::get_color()
{
How many Color return (col);
objects are we going }
to need?—
void Color::set_color(int c)
{
Here’s where we use
col = (c % 16);
the flyweight!! }

Make 3 Color objects bool Color:: operator == (Color &c)


and let the cards {
return (col == c.col;)
share them
}
L17 Feb. 24, 2010 – friends and software reuse
Number
• The Number attribute says how many Symbols are
on the card
• In a general implementation, it also indicates where
each of the symbols should be drawn
– If there is 1 symbol, it is in the middle
– If there are 2 or 3, they are centered in the card vertically
– The idea is that all cards with, say, 3 symbols on them will
draw them in the same relative position on the card
• This means that it will not work to have the Number
be a simple integer (1, 2, or 3).
– It needs to be a vector of (x,y) locations
– Then the number of symbols is the length of the vector
• How many numbers do we need?
– Three, so use the Flyweight here, too!!
Symbol
• The symbol (in a general graphical game) is a shape
• We could indeed think of a symbol as a string or a
character
• What is the most important thing a symbol has to
do?
– Know how to draw itself
– So – its most important method would be a draw() method
• But each symbol will be drawn differently!
– That means that each symbol has to belong to its own
class so that the draw method for it can be specific to it.
• And each card also has a shading associated with it,
so the draw method should have a shading
argument:
– draw(Shading s)
Class Structure for Symbol

The draw method for a Symbol is polymorphic – the draw method of


the base class Symbol would be a pure virtual method and the derived
classes would display the proper symbol
Using the Attributes of a Card
• We’ve discussed three of the attributes:
– Color
– Number
– Symbol
• We haven’t yet talked about Shading, but that’s
for a reason: it can be more complicated
• The role of the attributes is
– To use in checking whether a group of 3 Cards
makes a Set
• Turns out this is pretty easy
– To use when the Card draws itself
• The Card has to use the Color and the Number (with its vector of
locations) to guide the drawing, but it’s going to delegate the job of
actually drawing the shapes to Symbol
Checking to see if we have a Set
• We can make a method for the class Card like this:
bool Card::isSetSymbol (Card c1, Card c2, Card c3)
{
If (c1.sym == c2.sym && c2.sym == c3.sym) ||
(c1.sym != c2.sym && c1.sym != c3.sym &&
c2.sym != c3.sym)
return true;
else return false;
}
• And we make similar methods isSetNumber,
isSetColor, and isSetShading
• Then we can easily tell if a collection of 3 cards is a
Set
What about drawing the card?
• The Card uses the Color and the Number (with
its vector of locations) to guide the drawing, but
remember that it’s going to delegate the job of
actually drawing the shapes to Symbol
• But remember that the concept of having an
algorithm delegate responsibility for some part of
its function to some helper object is called the
Strategy Design Pattern
– This simplifies the card’s draw code
– But to do it, we do have to define the abstract class
Symbol and its derived classes Diamond, Oval, and
Squiggle
―Pseudocode‖ for drawing the Card
Remember that we have:
• Card with its private members col, num, sym, and
shade
• The class Symbol has a draw method, and we’ll let that
draw method have a single argument: a Shading

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!!

You might also like