design patterns. properties of good design minimize complexity maintainable loose coupling...
TRANSCRIPT
Design Patterns
Properties of good design
• Minimize complexity• Maintainable • Loose coupling• Extensibility• Reusability• High fan in• Low to medium fan out• Portability• Leanness • Stratification• Standard techniques
Some principles of good design
• Open-Close Principle• Dependency Inversion Principle• Interface Segregation Principle• Single Responsibility Principle• Liskov’s Substitution Principle• No forgery principle (keep data in a single
place)• One rule one place (don’t duplicate code)
What is wrong with this picture?
Ball
double gravity 32.1Private:
Enemy
double gravity 32.1Private:
No forgery!
How about this?
Global double gravity 3.21
Why not use globals?
A. They make code hard to understand.
B. They make code hard to debug.
C. They make code hard to modify.
Why not use globals?
D. Profs O’Neill and Kuenning with haunt your dreams if you do.
Answer
All of the above.
Singleton Pattern
Problem: Ensure a class has only one instance and provide a global point of access to that instance.
Singleton Class
class Singleton
{
public:
static Singleton* getInstance();
private:
static Singleton* theSingletonInstance;
Singleton() {};
~Singleton() {};
Singleton(const Singleton& toCopy) {};
Singleton& operator=(const Singleton& toCopy) {};
};
Singleton::Singleton* theSingletonInstance = NULL;
Instance Implementation
Singleton* getInstance()
{
if (theSingletonInstance == NULL)
theSingletonInstance = new Singleton;
return theSingletonInstance;
}
Exampleclass Ball
{
public:
static Ball* theBall();
tuple getPosition();
void setPosition(tuple newPosition);
private:
Sphere theSphere;
Ball() {};
~Ball() {};
tuple position;
};
Ball::Ball* theBall = NULL;
use:
Ball* myBall = Ball::getInstance();
what I want
I need a 2D graphics library that supports the following functions for triangles:– set color to r,g,b– translate vertices by dx, dy– rotate degrees about the origin – draw
what I have
I have a 3D graphics library with a triangle class with the following interface– triangle()– triangle(v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z)– ~triangle()– set color(r, g, b)– rotate(vector, angle)– translate(dx, dy, dz)– scale(sx, sy, sz)– draw()– flip(planeA, planeB, planeC, planeD)– texture(textureMap)– standardize()
just use the 3d class
• Constructor:
triangle t(v1x, v1y, 0, v2x, v2y, 0, v3x, v3y, 0)
• Rotate:
t.rotate(<0,0,1>,alpha)
Interface Segregation Principle
Solution
Triangle2D Triangle3D
implements the 2d triangle interface
façade
Problem: You need to use a subset of a complex system or you need to interact with the system in a particular way.
what I want
I want a physics engine that (among other things) detects collisions:
cCollision cPhysicsEngine::detectCollision(cPath p, cTriangles t)
I have a fast collision detection algorithm and a slower, more robust algorithm.
cPhysicsEngine
cPhysicsFast
How about this?
cPhysicsSlow
In the future I may want to use a super slow algorithm.
cPhysicsEngine cDetectCollision
cDetectCollisionFast
Strategy Design Pattern
cDetectCollisionSlow
supports open-close and single responsibility principles
Strategy design pattern
Problem: Want to be able to swap the algorithm used in an application.
Bridge vs. Strategy
Shape Drawer
Low ResHi Res
cPhysicsEngine cDetectCollision
cDetectCollisionFast cDetectCollisionSlow
Different intents: • bridge allows implementation to vary and includes adapters• strategy allows algorithms (behavior) to vary
DP hi res DP hi res
what I want
I am building a drawing program. The user enters keystrokes to change modes (Add, Delete, Move) and mouse input that is interpreted based on the current mode.
what I have
global int mode;
drawer.processMouse(key,position) {if mode==add
processMouseAddMode(key,position)else if mode==delete
processMouseDeleteMode(key,position)else if mode==move
processMouseMoveMode(key,position)}
DrawerprocessKeyprocessMouse
DeleteDrawerAddDrawer MoveDrawer
How about this
DrawerprocessKey
processMouse
ModeprocessMouse
DeleteAdd Move
State Design Pattern
1
supports open-close and single responsibility principles
DrawerprocessKey
processMouse
ModeprocessMouse
DeleteAdd Move
State Design Pattern
1
ModeManagerprocessKey
1 1 1
1
Mode mgr. returns pointer to correct mode
State Design Pattern
Problem: want to allow an object to alter its behavior when its internal state changes
State vs. Strategy
DrawerprocessKey
processMouse
ModeprocessMouse
DeleteAdd Move
1
ModeManagerprocessKey
1 1 1
1
cPhysicsEngine cDetectCollision
cDetectCollisionFast cDetectCollisionSlow
Different intents: • state allows behaviors to vary dynamically• strategy typically used when algorithm is selected at start
Problem continued
• I also want to support “Undo”
• Help!
Command
MouseKey Menu
Command Design Pattern
Command Design Pattern
Encapsulate a request as an object to permit logging, queuing, un-doing etc.
what I want
• I want a 2D drawing program that supports triangle and lines
• I want to be able to add, delete, draw, and move primitives.
• I want to be also want to be able to group primitives into a “widget” and treat the widget as a primitive.
• I want to be able to add and delete primitives from a widget
solution 1
Widget Shape*
Triangle Line
What is the difference between a triangle and a widget holding a triangle?
Composite Design Pattern
Widget
Shape*
Triangle Line
Abstract factory
Observer Design Pattern
Observer Design Pattern
Other design patterns
wikipedia!