大问题化为多个小问题,复杂问题分解为多个简单问题。
忽视非本质细节,抽取为微内核对象模型。
高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)。
抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。
对扩展开放,对更改封闭。(不更改已有类文件,新增文件进行扩展)
类模块可扩展,但是不可修改。
一个类应该仅有一个引起变化的原因。
变化的方向隐含着类的责任。
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4OfwO2Y9-1652451824231)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220417204458212.png)]
代码
//Operation.h
#ifndef OPERATION_H_
#define OPERATION_H_
class Operation
{
public:
Operation(void);
~Operation(void);
virtual double GetResult();
void SetNumA(double fValueA);
void SetNumB(double fValueB);
protected:
double m_fNumberA;
double m_fNumberB;
};
#endif
//Operation.cpp
#include "Operation.h"
Operation::Operation(void)
: m_fNumberA(0)
, m_fNumberB(0)
{
}
Operation::~Operation(void)
{
}
double Operation::GetResult()
{
double fResult = 0;
return fResult;
}
void Operation::SetNumA(double fValueA)
{
m_fNumberA = fValueA;
}
void Operation::SetNumB(double fValueB)
{
m_fNumberB = fValueB;
}
//Add.h
#ifndef ADD_H_
#define ADD_H_
#include "Operation.h"
class Add : public Operation
{
public:
Add(void);
~Add(void);
virtual double GetResult();
};
#endif
//Add.cpp
#include "Add.h"
Add::Add(void)
{
}
Add::~Add(void)
{
}
double Add::GetResult()
{
double fResult = 0;
fResult = m_fNumberA + m_fNumberB;
return fResult;
}
//Subtract.h
#ifndef SUBTRACT_H_
#define SUBTRACT_H_
#include "Operation.h"
class Subtract : public Operation
{
public:
Subtract(void);
~Subtract(void);
virtual double GetResult();
};
#endif
//Subtract.cp
#include "Subtract.h"
Subtract::Subtract(void)
{
}
Subtract::~Subtract(void)
{
}
double Subtract::GetResult()
{
double fResult = 0;
fResult = m_fNumberA - m_fNumberB;
return fResult;
}
//Multi.h
#ifndef MULTIPLY_H_
#define MULTIPLY_H_
#include "Operation.h"
class Multiply : public Operation
{
public:
Multiply(void);
~Multiply(void);
virtual double GetResult();
};
#endif
//multi.cpp
#include "Multiply.h"
Multiply::Multiply(void)
{
}
Multiply::~Multiply(void)
{
}
double Multiply::GetResult()
{
double fResult = 0;
fResult = m_fNumberA * m_fNumberB;
return fResult;
}
//Divide.h
#ifndef DIVIDE_H_
#define DIVIDE_H_
#include "Operation.h"
class Divide : public Operation
{
public:
Divide(void);
~Divide(void);
virtual double GetResult();
};
#endif
//Divide.cpp
#include "Divide.h"
Divide::Divide(void)
{
}
Divide::~Divide(void)
{
}
double Divide::GetResult()
{
double fResult = 0;
if (m_fNumberB != 0)
{
fResult = m_fNumberA / m_fNumberB;
}
return fResult;
}
//Factory.h
#ifndef OPERATION_FACTORY_H_
#define OPERATION_FACTORY_H_
#include "Operation.h"
enum OperationType
{
OperationType_Start,
OperationType_Add = OperationType_Start,
OperationType_Sub,
OperationType_Multi,
OperationType_Divide,
OperationType_MAX,
};
class OperationFactory
{
public:
OperationFactory(void);
~OperationFactory(void);
Operation* CreateOperation(OperationType eType);
private:
Operation* m_pOperation;
};
#endif
//Factory.cpp
#include "OperationFactory.h"
#include "Add.h"
#include "Subtract.h"
#include "Multiply.h"
#include "Divide.h"
OperationFactory::OperationFactory(void)
: m_pOperation(0)
{
}
OperationFactory::~OperationFactory(void)
{
if (0 != m_pOperation)
{
delete m_pOperation;
m_pOperation = 0;
}
}
Operation* OperationFactory::CreateOperation(OperationType eType)
{
switch (eType)
{
case OperationType_Add:
m_pOperation = new Add();
break;
case OperationType_Sub:
m_pOperation = new Subtract();
break;
case OperationType_Multi:
m_pOperation = new Multiply();
break;
case OperationType_Divide:
m_pOperation = new Divide();
break;
default:
break;
}
return m_pOperation;
}
//main.cpp
#include "Add.h"
#include "Divide.h"
#include "Subtract.h"
#include "Multiply.h"
#include "OperationFactory.h"
#include "stdio.h"
int main()
{
OperationFactory* pFactory = new OperationFactory();
Operation* pOperation = pFactory->CreateOperation(OperationType_Add);
pOperation->SetNumA(3.14);
pOperation->SetNumB(2.43);
float fResult = pOperation->GetResult();
printf("The value of the result: %f2", fResult);
return 0;
}
相关模式分析
与策略模式对比分析
工厂模式
public class OperationFactory
{
public static Operation CreateOperate (string operate)
{
Operation oper=null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
oper = new Operation();
break;
}
return oper;
}
}
策略模式
class Context
{
CashSuper csuper;
public Context(CashSuper cs)
{
this.csuper = cs;
}
public double GetResult(double money)
{
//调用具体策略类的收费方法
return csuper.acceptCash(money);
}
}
1.从类型上说:简单工厂模式属于创建型模式,而策略模式属于行为型模式。
2.接下来,看一个小例子:
斧子有很多种,有一个工厂专门负责生产各种需求的斧子。
工厂模式:
1)根据你给出的目的来生产不同用途的斧子,例如要砍人,那么工厂生产砍人斧子,要伐木就生产伐木斧子。
2)即根据你给出一些属性来生产不同行为的一类对象返回给你。
3)关注对象创建
策略模式:
1)用工厂生产的斧子来做对应的事情,例如用砍人的斧子来砍人,用伐木的斧子来伐木。
2)即根据你给出对应的对象来执行对应的方法。
3)关注行为的选择
3.简单工厂模式:根据客户选择的条件,来帮客户创建一个对象。
策略模式:客户给它一个创建好的对象,它来帮客户做相应的事。
意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到子类。
动机
框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。考虑这样一个应用框架,它可以向用户显示多个文档,在这个框架中,两个主要的抽象类是Application和Document。这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义类DrawingApplication和DrawingDocument。Application负责管理Document并根据需要创建它们。因此被实例化的特定Document与特定应用相关,所以Application类不可能预测到哪个子类将被实例化。Factory Method提供了一个解决方案。它封装了哪个Document子类将被创建的信息并将这些信息从该框架中分离出来。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VRPs9zAO-1652451824233)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220418223046925.png)]
参与者
效果
代码示例
//Creator.h
#ifndef CREATOR_H_
#define CREATOR_H_
class IProduct;
enum ProductType
{
ProductType_Start,
ProductType_Me = ProductType_Start,
ProductType_You,
ProductType_Max,
};
class Creator
{
public:
Creator(void);
virtual ~Creator(void);
//参数工厂方法
virtual IProduct* GetProduct(ProductType eType);
virtual IProduct* Create(ProductType eProductType = ProductType_Max);
private:
IProduct* m_pProduct;
};
#endif
//Creator.cpp
#include "Creator.h"
#include "MyProductA.h"
#include "YourProduct.h"
Creator::Creator(void)
:m_pProduct(0)
{
}
Creator::~Creator(void)
{
delete m_pProduct;
m_pProduct = 0;
}
IProduct* Creator::GetProduct(ProductType eType)
{
if (0 == m_pProduct)
{
m_pProduct = Create(eType);
}
return m_pProduct;
}
IProduct* Creator::Create(ProductType eProductType /*= ProductType_Max*/)
{
if (ProductType_Me == eProductType)
{
return new MyProductA();
}
else if (ProductType_You == eProductType)
{
return new YourProduct();
}
}
//SpecialCreator.h
#include "Creator.h"
class SpecialCreator : public Creator
{
public:
SpecialCreator(void);
virtual ~SpecialCreator(void);
virtual IProduct* Create(ProductType eProductType /* = ProductType_Max */);
};
//SpecialCreator.cpp
#include "SpecialCreator.h"
#include "MyProductA.h"
#include "YourProduct.h"
SpecialCreator::SpecialCreator(void)
{
}
SpecialCreator::~SpecialCreator(void)
{
}
IProduct* SpecialCreator::Create(ProductType eProductType /* = ProductType_Max */)
{
if (ProductType_Me == eProductType)
{
return new YourProduct;
}
else if (ProductType_You == eProductType)
{
return new MyProductA;
}
}
//StandardCreator.h
#ifndef STANDARD_CREATOR_H_
#define STANDARD_CREATOR_H_
#include "Creator.h"
template
class StandardCreator : public Creator
{
public:
StandardCreator(void);
virtual ~StandardCreator(void);
virtual IProduct* Create(ProductType eType);
};
template
StandardCreator::~StandardCreator(void)
{
}
template
StandardCreator::StandardCreator(void)
{
}
template
IProduct* StandardCreator::Create(ProductType eType)
{
return new TheProduct;
}
#endif
//StandardCreator.cpp
#include "StandardCreator.h"
//Iproduct.h
#ifndef IPRODUCT_H_
#define IPRODUCT_H_
class IProduct
{
public:
IProduct(void);
virtual ~IProduct(void);
};
#endif
//Iproduct.cp
#include "IProduct.h"
IProduct::IProduct(void)
{
}
IProduct::~IProduct(void)
{
}
//MyProductA.h
#ifndef MY_PRODUCT_H_
#define MY_PRODUCT_H_
#include "IProduct.h"
class MyProductA : public IProduct
{
public:
MyProductA(void);
virtual ~MyProductA(void);
};
#endif
//MyProductA.cpp
#include "MyProductA.h"
#include
MyProductA::MyProductA(void)
{
printf("MyProductA Created!\n");
}
MyProductA::~MyProductA(void)
{
printf("MyProductA Destroyed!\n");
}
//YourProduct.h
#ifndef YOUR_PRODUCT_H_
#define YOUR_PRODUCT_H_
#include "IProduct.h"
class YourProduct : public IProduct
{
public:
YourProduct(void);
virtual ~YourProduct(void);
};
#endif
//YourProduct.cpp
#include "YourProduct.h"
#include
YourProduct::YourProduct(void)
{
printf("YourProduct Created!\n");
}
YourProduct::~YourProduct(void)
{
printf("YourProduct Destroyed!\n");
}
//main.cpp
#include "Creator.h"
#include "YourProduct.h"
#include "MyProductA.h"
#include "SpecialCreator.h"
#include "StandardCreator.h"
#include
int main()
{
IProduct* pProduct = 0;
Creator* pCreator = 0;
pCreator = new Creator();
//使用第一种工厂方法所见即所得
pProduct = pCreator->Create(ProductType_Me);
delete pCreator;
pCreator = 0;
//使用第二种工厂方法,所见非所得
pCreator = new SpecialCreator();
pProduct = pCreator->Create(ProductType_Me);
delete pCreator;
pCreator = 0;
//使用第三种工厂方法,模板方法
pCreator = new StandardCreator();
pProduct = pCreator->Create();
delete pCreator;
pCreator = 0;
pCreator = new StandardCreator();
pProduct = pCreator->Create();
delete pCreator;
pCreator = 0;
system("pause");
return 0;
}
相关模式
意图
提供一个接口,创建一系列相关或相互依赖的对象,而无须指定他们具体的类。
动机
考虑一个支持多种视感标准的用户界面工具包。不同的视感风格为诸如滚动条、窗口和按钮等用户界面窗口组件定义不同的外观和行为。为保证视感风格标准之间的可移植性,一个应用不应该为一个特定的视感分割外观硬编码它的窗口组件。在整个应用中实例化特定视感风格的窗口组件类,使得以后很难改变视感风格。
为解决这一问题,我们可以定义一个抽象的WidgetFactory类,这个类声明了一个用来创建每一类基本窗口的接口。每一类窗口组件都有一个抽象类,而具体子类实现了窗口组件的特定视感风格。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nO0SSPS2-1652451824234)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220419074442558.png)]
参与者
效果
代码示例
#ifndef MAZE_FACTORY_H_
#define MAZE_FACTORY_H_
class IMaze;
class IWall;
class IRoom;
class IDoor;
class MazeFactory
{
public:
MazeFactory(void);
virtual IMaze* MakeMaze() const {return new IMaze;};
virtual IWall* MakeWall() const {return new IWall;};
virtual IRoom* MakeRoom(int nRoomNo) const {return new IRoom(nRoomNo);};
virtual IDoor* MakeDoor(IRoom* pRoom1, IRoom* pRoom2) const {return new IDoor(pRoom1, pRoom2);};
~MazeFactory(void);
};
#endif
#include "MazeFactory.h"
class BombedFactory : public MazeFactory
{
public:
BombedFactory(void);
~BombedFactory(void);
IWall* MakeWall();
IDoor* MakeDoor(IRoom* pRoom1, IRoom* pRoom2);
};
#include "BombedFactory.h"
#include "BombedDoor.h"
#include "BombedWall.h"
BombedFactory::BombedFactory(void)
{
}
BombedFactory::~BombedFactory(void)
{
}
IWall* BombedFactory::MakeWall()
{
return new BombedWall;
}
IDoor* BombedFactory::MakeDoor(IRoom* pRoom1, IRoom* pRoom2)
{
return new BombedDoor;
}
#ifndef ENCHANTED_MAZE_FACTORY_H_
#define ENCHANTED_MAZE_FACTORY_H_
#include "MazeFactory.h"
class EnchantedMazeFactory : public MazeFactory
{
public:
EnchantedMazeFactory(void);
~EnchantedMazeFactory(void);
virtual IRoom* MakeRoom(int nRoomNo) const;
virtual IDoor* MakeDoor(IRoom* pRoom1, IRoom* pRoom2) const;
protected:
Spell* CastSpell() const;
};
#endif
#include "EnchantedMazeFactory.h"
#include "EnchantedRoom.h"
#include "DoorNeedingSpell.h"
EnchantedMazeFactory::EnchantedMazeFactory(void)
{
}
EnchantedMazeFactory::~EnchantedMazeFactory(void)
{
}
IRoom* EnchantedMazeFactory::MakeRoom(int nRoomNo) const
{
return new EnchantedRoom(nRoomNo, CastSpell());
}
IDoor* EnchantedMazeFactory::MakeDoor(IRoom* pRoom1, IRoom* pRoom2) const
{
return new DoorNeedingSpell(pRoom1, pRoom2);
}
#ifndef IMAZE_H_
#define IMAZE_H_
class IRoom;
class IMaze
{
public:
IMaze(void);
~IMaze(void);
void AddRoom(IRoom* pRoom);
IRoom* RoomNo(int nNo) const;
};
#endif
#ifndef MAZE_GAME_H_
#define MAZE_GAME_H_
#include "MazeFactory.h"
#include "IMaze.h"
class MazeGame
{
public:
MazeGame(void);
~MazeGame(void);
IMaze* CreateMaze(MazeFactory& clsFactory);
};
#endif
#include "MazeGame.h"
#include "IRoom.h"
MazeGame::MazeGame(void)
{
}
MazeGame::~MazeGame(void)
{
}
IMaze* MazeGame::CreateMaze(MazeFactory& clsFactory)
{
IMaze* pMaze = clsFactory.MakeMaze();
IRoom* pRoom1 = clsFactory.MakeRoom(1);
IRoom* pRoom2 = clsFactory.MakeRoom(2);
IDoor* pDoor = clsFactory.MakeDoor(pRoom1, pRoom2);
pMaze->AddRoom(pRoom1);
pMaze->AddRoom(pRoom2);
for (int nIndex = Direction_Start; nIndex < Direction_Max; nIndex++)
{
pRoom1->SetSide((RoomDirection)nIndex, (MapSite*)clsFactory.MakeWall());
pRoom2->SetSide((RoomDirection)nIndex, (MapSite*)clsFactory.MakeWall());
}
pRoom1->SetSide(Direction_East, (MapSite*)pDoor);
pRoom2->SetSide(Direction_West, (MapSite*)pDoor);
return pMaze;
}
#ifndef SPELL_H_
#define SPELL_H_
class Spell
{
public:
Spell(void);
~Spell(void);
};
#endif
#ifndef IDOOR_H_
#define IDOOR_H_
#include "MapSite.h"
#include "IRoom.h"
class IDoor : public MapSite
{
public:
IDoor(IRoom* pRomm1, IRoom* pRoom2);
~IDoor(void);
virtual void Enter();
IRoom* OtherSideFrom(IRoom* pRoom);
private:
IRoom* m_pRoom1;
IRoom* m_pRoom2;
};
#endif
#ifndef IROOM_H_
#define IROOM_H_
#include "MapSite.h"
enum RoomDirection
{
Direction_Start,
Direction_North = Direction_Start,
Direction_South,
Direction_East,
Direction_West,
Direction_Max,
};
class IRoom : public MapSite
{
public:
IRoom(int nRoomNo);
~IRoom(void);
MapSite* GetSide(RoomDirection eDire) const;
void SetSide(RoomDirection eDire, MapSite* pSite);
virtual void Enter();
private:
std::map m_mapRootSite;
int m_nRoomNo;
};
#endif
#ifndef IWALL_H_
#define IWALL_H_
#include "MapSite.h"
class IWall : public MapSite
{
public:
IWall(void);
~IWall(void);
virtual void Enter();
};
#endif
#ifndef MAP_SITE_H_
#define MAP_SITE_H_
class MapSite
{
public:
MapSite(void);
~MapSite(void);
virtual void Enter() = 0;
};
#endif
相关模式
意图
将一个类的接口转换成客户需要的另外一个接口。Adapter模式使得原本由于接口不兼容而不能在一起工作的类可以一起工作。
动机
有时为复用而设计的工具箱类不能够被复用,仅仅是因为它的接口与专业应用领域所需的接口不匹配。
适用性
结构
类适配器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wnJKxjSq-1652451824234)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220507073321892.png)]
对象适配器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z0Iypba6-1652451824235)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220507073339053.png)]
参与者
效果
类适配器的权衡:
对象适配器的权衡:
实现
#ifndef _SHAPE_H_
#define _SHAPE_H_
#include
class Manipulator;
class Shape
{
public:
Shape(void);
~Shape(void);
virtual void BoundingBox(Point& clsBottomLeft, Point& clsTopRight);
virtual Manipulator* CreateManipulator() const;
};
#endif
#ifndef _TEXT_VIEW_H_
#define _TEXT_VIEW_H_
#include
class TextView
{
public:
TextView(void);
~TextView(void);
void GetOrigin(COORD& clsX, COORD& clsY);
void GetExtent(COORD& clsWidth, COORD& clsHeight);
virtual bool IsEmpty() const;
};
#endif
#ifndef _TEXT_SHAPE_H_
#define _TEXT_SHAPE_H_
#include "Shape.h"
#include "TextView.h"
//通过多继承适配不同接口
class Manipulator;
class TextShape : public Shape, public TextView
{
public:
TextShape(void);
~TextShape(void);
virtual void BoundingBox(Point& clsBottomLeft, Point& clsTopRight);
virtual bool IsEmpty();
virtual Manipulator* CreateManipulator();
};
#endif
#include "TextShape.h"
TextShape::TextShape(void)
{
}
TextShape::~TextShape(void)
{
}
void TextShape::BoundingBox(Point& clsBottomLeft, Point& clsTopRight)
{
COORD clsBottom, clsLeft, clsWidth, clsHeight;
GetOrigin(clsBottom, clsLeft);
GetExtent(clsWidth, clsHeight);
clsBottomLeft = Point(clsBottom, clsLeft);
clsTopRight = Point(clsBottom + clsHeight, clsLeft + clsWidth);
}
bool TextShape::IsEmpty()
{
return TextView::IsEmpty();
}
Manipulator* TextShape::CreateManipulator()
{
return new Manipulator(this);
}
#ifndef _TEXT_SHAPE_H_
#define _TEXT_SHAPE_H_
#include "Shape.h"
//对象适配器
class TextShapeObj : public Shape
{
public:
TextShapeObj(TextView* pTextView);
~TextShapeObj(void);
virtual void BoundingBox(Point& clsBottomLeft, Point& clsTopRight);
virtual bool IsEmpty();
virtual Manipulator* CreateManipulator();
private:
TextView* m_pTextView;
};
#endif
#include "TextShapeObj.h"
#include
#include
TextShapeObj::TextShapeObj(TextView* pTextView)
: m_pTextView(pTextView)
{
}
TextShapeObj::~TextShapeObj(void)
{
}
void TextShapeObj::BoundingBox(Point& clsBottomLeft, Point& clsTopRight)
{
if (NULL == m_pTextView)
{
assert(false);
return;
}
COORD clsBottom, clsLeft, clsWidth, clsHeight;
m_pTextView->GetOrigin(clsBottom, clsLeft);
m_pTextView->GetExtent(clsWidth, clsHeight);
clsBottomLeft = Point(clsBottom, clsLeft);
clsTopRight = Point(clsBottom + clsHeight, clsLeft + clsWidth);
}
bool TextShapeObj::IsEmpty()
{
if (NULL == m_pTextView)
{
assert(false);
return;
}
return m_pTextView->IsEmpty();
}
Manipulator* TextShapeObj::CreateManipulator()
{
return new Manipulator(this);
}
相关模式
意图
将抽象部分与它的实现部分分离,使它们可以独立地变化(本质上来说该事务在多个维度变化)。
动机
当一个抽象有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但是此方法有时不够灵活。继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分进行修改、扩充和复用。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zg0p2KRL-1652451824235)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220509072217574.png)]
参与者
效果
实现
#ifndef _WINDOW_H_
#define _WINDOW_H_
class WindowImp;
class Window
{
public:
Window(View* pContents);
virtual ~Window(void);
virtual void DrawContents();
virtual void Open();
virtual void Close();
virtual void Iconfy();
virtual void Deiconify();
virtual void SetOrigin(const Point& clsAt);
virtual void SetExtent(const Point& clsExtent);
virtual void Raise();
virtual void Lower();
virtual void DrawLine(const Point& clsPointStart, const Point& clsPointEnd);
virtual void DrawRrect(const Point& clsPointTopLeft, const Point& clsPointRightBottom);
virtual void DrawPlygon(const Point [] aPonts, int n);
virtual void DrawText(const char* pChar, const Point& clsPoint);
protected:
WindowImp* GetWindowImp();
View* GetView();
private:
WindowImp* m_pImp;
View* m_pContents;
};
#endif
#include "Window.h"
#include
#include
#include
void Window::DrawRrect(const Point& clsPointTopLeft, const Point& clsPointRightBottom)
{
WindowImp* pImp = GetWindowImp();
pImp->ImpDeviceRect(clsPointTopLeft.X, clsPointTopLeft.Y, clsPointRightBottom.X, clsPointRightBottom.Y);
}
WindowImp* Window::GetWindowImp()
{
if (NULL == m_pImp)
{
m_pImp WindowSystemFactory::Instance()->MakeWindowImp();
}
return m_pImp;
}
#ifndef _APPLICATION_WINDOW_H_
#define _APPLICATION_WINDOW_H_
#include "Window.h"
class ApplicationWindow : public Window
{
public:
ApplicationWindow(void);
virtual ~ApplicationWindow(void);
virtual void DrawContents();
};
#endif
#include "ApplicationWindow.h"
ApplicationWindow::ApplicationWindow(void)
{
}
ApplicationWindow::~ApplicationWindow(void)
{
}
void ApplicationWindow::DrawContents()
{
GetView()->DrawOn(this);
}
#ifndef _ICON_WINDOW_H_
#define _ICON_WINDOW_H_
#include "Window.h"
class IconWindow : public Window
{
public:
IconWindow(void);
virtual ~IconWindow(void);
virtual void DrawContents();
private:
const char* m_pBitName;
};
#endif
#include "IconWindow.h"
IconWindow::IconWindow(void)
{
}
IconWindow::~IconWindow(void)
{
}
void IconWindow::DrawContents()
{
WindowImp* pImp = GetWindowImp();
pImp->DeviceBitMap(m_pBitName, 0.0, 0.0);
}
#ifndef _WINDOW_IMP_H_
#define _WINDOW_IMP_H_
class WindowImp
{
public:
virtual ~WindowImp(void);
public:
virtual void ImpTop() = 0;
virtual void ImpBottom() = 0;
virtual void ImpSetExtent() = 0;
virtual void ImpSetOrigin() = 0;
virtual void ImpDeviceRect() = 0;
virtual void ImpDeviceText() = 0;
virtual void ImpBitmap() = 0;
virtual void ImpTop() = 0;
virtual void ImpTop() = 0;
virtual void ImpTop() = 0;
protected:
WindowImp(void);
};
#endif
#include "WindowImp.h"
WindowImp::WindowImp(void)
{
}
WindowImp::~WindowImp(void)
{
}
#ifndef _XWINDOW_IMP_
#define _XWINDOW_IMP_
#include "WindowImp.h"
class XWindowImp : public WindowImp
{
public:
XWindowImp(void);
~XWindowImp(void);
virtual void DeviceRect(COORD clsCoord1, COORD clsCoord2, COORD clsCoord3, COORD clsCoord4);
private:
Display* m_pDsp;
Drawable m_clsWinid;
GC m_gc;
};
#endif
#include "XWindowImp.h"
#include
XWindowImp::XWindowImp(void)
{
}
XWindowImp::~XWindowImp(void)
{
}
void XWindowImp::DeviceRect(COORD clsCoord1, COORD clsCoord2, COORD clsCoord3, COORD clsCoord4)
{
int x = round(min(clsCoord1, clsCoord3));
int y = round(min(clsCoord2, clsCoord4));
int w = round(abs(clsCoord1-clsCoord3));
int h = round(abs(clsCoord2-clsCoord4));
XDrawRectangle(m_pDsp, m_clsWinid, m_gc, m_gc, x, y, w, h);
}
#ifndef _PM_WINDOW_IMP_
#define _PM_WINDOW_IMP_
#include "WindowImp.h"
class PMWindowImp : public WindowImp
{
public:
PMWindowImp(void);
~PMWindowImp(void);
virtual void DeviceRect(COORD clsCoord1, COORD clsCoord2, COORD clsCoord3, COORD clsCoord4);
private:
HPS m_hps;
};
#endif
#include "PMWindowImp.h"
#include
#include
PMWindowImp::PMWindowImp(void)
{
}
PMWindowImp::~PMWindowImp(void)
{
}
void PMWindowImp::DeviceRect(COORD clsCoord1, COORD clsCoord2, COORD clsCoord3, COORD clsCoord4)
{
COORD clsLeft = min(clsCoord1, clsCoord3);
COORD clsRight = max(clsCoord2, clsCoord4);
COORD clsBottom = abs(clsCoord1-clsCoord3);
COORD clsTop = abs(clsCoord2-clsCoord4);
PPOINTL point[4];
point[0].x = clsLeft; point[0].y = clsTop;
point[1].x = clsRight; point[1].y = clsTop;
point[2].x = clsRight; point[2].y = clsBottom;
point[3].x = clsLeft; point[3].y = clsBottom;
if (
(GpiBeginPath(m_hps, 1L) == false) ||
(GpiSetCurrentPosition(m_hps, &point[3]) == false) ||
(GpiPolyLine(m_hps, 4L, point) == GPI_ERROR) ||
(GpiEndPath(m_hps) == false)
)
{
//Report Error
}
else
{
GpiStrokePath(m_hps, 1L, 0L);
}
}
相关模式
意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
动机
在绘图编辑器和图形捕捉系统这样的图形应用系统中,用户可以使用简单的组件创建复杂的图表。用户可以组合多个简单组件组成以向较大的组件,这些组件又可以组合成更大的组件。
Composite模式的关键就是一个抽象类,它既可以表示图元,又可以表示图元的容器。
适用性
结构
参与者
效果
实现
相关模式
意图
动机
适用性
结构
参与者
效果
实现
相关模式
意图
处理发起请求和请求处理之间的逻辑。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到一个对象处理它。
动机
考虑一个学生请假的场景,学生请假小于或等于2天,班主任可以批准,小于或等于7天,系主任可以批准;小于或等于10天,院长可以批准;其他情况不予批准。这个场景涉及到不同角色的对象对学生请假的请求进行处理,可以采用责任链模式解决。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9bJ5ONY-1652451824236)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220416205459261.png)]
参与者
效果
实现
//Leader.h
#ifndef LEADER_H_
#define LEADER_H_
class Leader
{
public:
Leader(Leader* pLeader);
~Leader(void);
virtual void HandleRequest(int nLeaveDays);
private:
Leader* m_pLeader;
};
#endif
//Leader.cpp
#include "Leader.h"
Leader::Leader(Leader* pLeader)
: m_pLeader(pLeader)
{
}
Leader::~Leader(void)
{
}
void Leader::HandleRequest(int nLeaveDays)
{
if (0 != m_pLeader)
{
//������������һ������
m_pLeader->HandleRequest(nLeaveDays);
}
}
//ClassAdviser.h
#ifndef CLASS_ADVISER_H_
#define CLASS_ADVISER_H_
#include "Leader.h"
class ClassAdviser : public Leader
{
public:
ClassAdviser(Leader* pLeader);
~ClassAdviser(void);
virtual void HandleRequest(int nLeaveDays);
};
#endif
//ClassAdviser.cpp
#include "ClassAdviser.h"
ClassAdviser::ClassAdviser(Leader* pLeader)
: Leader(pLeader)
{
}
ClassAdviser::~ClassAdviser(void)
{
}
void ClassAdviser::HandleRequest(int nLeaveDays)
{
if (2 >= nLeaveDays)
{
cout << "adviser permit the vocation!" << endl;
}
else
{
cout << "adviser can't permit the vocation! submit the request" << endl;
Leader::HandleRequest(nLeaveDays);
}
}
//DeanDepartment.h
#ifndef DEPARTMENT_LEADER_H_
#define DEPARTMENT_LEADER_H_
#include "Leader.h"
class DepartmentLeader : public Leader
{
public:
DepartmentLeader(Leader* pLeader);
~DepartmentLeader(void);
virtual void HandleRequest(int nLeaveDays);
};
#endif
//DeanDepartment.cpp
#include "DepartmentLeader.h"
DepartmentLeader::DepartmentLeader(Leader* pLeader)
: Leader(pLeader)
{
}
DepartmentLeader::~DepartmentLeader(void)
{
}
void DepartmentLeader::HandleRequest(int nLeaveDays)
{
if (7 >= nLeaveDays)
{
cout << "Department Leader permit the vocation!" << endl;
}
else
{
cout << "Department Leader can't permit, submit the request!" << endl;
Leader::HandleRequest(nLeaveDays);
}
}
//Dean.h
#ifndef DEAN_H_
#define DEAN_H_
#include "Leader.h"
class Dean : public Leader
{
public:
Dean(Leader* pLeader);
~Dean(void);
virtual void HandleRequest(int nLeaveDays);
};
#endif
//Dean.cpp
#include "Dean.h"
Dean::Dean(Leader* pLeader)
: Leader(pLeader)
{
}
Dean::~Dean(void)
{
}
void Dean::HandleRequest(int nLeaveDays)
{
if (10 >= nLeaveDays)
{
cout << "Dean permit the vocation!" << endl;
}
else
{
cout << "Dean can't permit, no one can handle the request!" << endl;
}
}
//main.cpp
#include "Leader.h"
#include "Dean.h"
#include "ClassAdviser.h"
#include "DepartmentLeader.h"
int main()
{
Leader* pDean = new Dean(0);
Leader* pDepartmentLeader = new DepartmentLeader(pDean);
Leader* pClassAdviser = new ClassAdviser(pDepartmentLeader);
pClassAdviser->HandleRequest(8);
return 0;
}
相关模式
意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录清楚日志,以及支持可撤销的操作。
动机
用户界面工具箱包括按钮和菜单这样的对象,它们执行请求响应用户输入。但是工具箱不能显示的在按钮或者菜单中实现该请求,因为只有工具箱的应用代码知道该由哪个对象做哪个操作。
命令模式通过将请求本身变成一个对象来使工具对象可向未指定的应用对象提出请求。这个对象可以被存储,或者传递。这一模式的关键是一个抽象的command,它定义了执行操作的接口。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTBT2Cjm-1652451824236)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220505225558262.png)]
参与者
效果
代码示例
#ifndef _COMMAND_H_
#define _COMMAND_H_
class Command
{
public:
virtual ~Command(void);
virtual void Excute() = 0;
protected:
Command(void);
};
#endif
#ifndef _MACRO_COMMAND_H_
#define _MACRO_COMMAND_H_
#include "Command.h"
#include
#include
using namespace std;
class MacroCommand : public Command
{
public:
MacroCommand(void);
virtual ~MacroCommand(void);
virtual void Add(Command* pCommand);
virtual void remove(Command* pCommand);
virtual void Excute();
private:
list m_listCommand;
};
#endif
#include "MacroCommand.h"
#include
using namespace std;
MacroCommand::MacroCommand(void)
{
}
MacroCommand::~MacroCommand(void)
{
}
void MacroCommand::Add(Command* pCommand)
{
m_listCommand.push_back(pCommand);
}
void MacroCommand::remove(Command* pCommand)
{
m_listCommand.remove(pCommand);
}
void MacroCommand::Excute()
{
std::list::iterator itor = m_listCommand.begin();
for (; itor != m_listCommand.end(); ++itor)
{
(*itor)->Excute();
}
}
#ifndef _OPEN_COMMAND_H_
#define _OPEN_COMMAND_H_
#include "Command.h"
class Application;
class OpenCommand : public Command
{
public:
OpenCommand(Application* pApplication);
virtual ~OpenCommand(void);
virtual void Excute();
protected:
virtual const char* AskUser();
private:
Application* m_pApplication;
char* m_pCResponse;
};
#endif
#include "OpenCommand.h"
#include
class Document;
OpenCommand::OpenCommand(Application* pApplication)
: m_pApplication(pApplication)
, m_pCResponse(NULL)
{
}
//具体的命令对象借助应用代码实现具体操作
void OpenCommand::Excute()
{
const char* pName = AskUser();
if (NULL != pName)
{
Document* pDocumnet = new Document(pName);
m_pApplication->Add(pDocumnet);
pDocumnet->Open();
}
}
#ifndef _PASTE_COMMAND_H_
#define _PASTE_COMMAND_H_
#include "Command.h"
class Document;
class PasteCommand : public Command
{
public:
PasteCommand(Document* pDocument);
virtual ~PasteCommand(void);
virtual void Excute();
private:
Document* m_pDocumnet;
};
#endif
#include "PasteCommand.h"
PasteCommand::PasteCommand(Document* pDocument)
: m_pDocumnet(pDocument)
{
}
void PasteCommand::Excute()
{
m_pDocumnet->Paste();
}
#ifndef _SIMPLE_COMMAND_H_
#define _SIMPLE_COMMAND_H_
#include "Command.h"
#include
#include
template
class SimpleCommand : public Command
{
public:
typedef void (Receiver::*Action)();
SimpleCommand(Receiver* pReceiver, Action a);
~SimpleCommand(void);
virtual void Excute();
private:
Action m_Action;
Receiver* m_pReceiver;
};
template
void SimpleCommand::Excute()
{
if (NULL == m_pReceiver)
{
assert(false);
return;
}
m_pReceiver->*m_Action();
}
template
SimpleCommand::SimpleCommand(Receiver* pReceiver, Action a)
: m_pReceiver(pReceiver)
, m_Action(a)
{
}
#endif
相关模式
意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示解释语言中的句子。
动机
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言的句子。这个样就可以构建一个解释器,该解释器通过解释这些句子解决该问题。例如,正则表达式是描述字符串模式的一种标准语言。与其为每一个模式都构造一个特定的算法,不如使用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了待匹配字符串的集合。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FHMxYbqX-1652451824236)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220427073831067.png)]
参与者
效果
代码示例
#ifndef BOOLEAN_EXP_H_
#define BOOLEAN_EXP_H_
#include"Context.h"
class BooleanExp
{
public:
BooleanExp();
virtual ~BooleanExp();
virtual bool Evaluate(Context& clsContext) = 0;
virtual BooleanExp* Replace(const char* pChar, BooleanExp& clsExp) = 0;
virtual BooleanExp* Copy() const = 0;
};
#endif // !BOOLEAN_EXP_H_
#ifndef AND_EXP_H_
#define AND_EXP_H_
#include "BooleanExp.h"
class AndExp :public BooleanExp
{
public:
AndExp(BooleanExp* pExp, BooleanExp* pExp2);
virtual ~AndExp();
virtual bool Evaluate(Context& clsContext);
virtual BooleanExp* Replace(const char* pChar, BooleanExp& clsExp);
virtual BooleanExp* Copy() const;
private:
BooleanExp* m_pOperate1;
BooleanExp* m_pOperate2;
};
#endif
#include "AndExp.h"
AndExp::AndExp(BooleanExp* pExp, BooleanExp* pExp2)
: m_pOperate1(pExp)
, m_pOperate2(pExp2)
{
}
bool AndExp::Evaluate(Context& clsContext)
{
return m_pOperate1->Evaluate(clsContext) && m_pOperate2->Evaluate(clsContext);
}
BooleanExp* AndExp::Replace(const char* pChar, BooleanExp& clsExp)
{
return new AndExp(m_pOperate1->Replace(pChar, clsExp), m_pOperate2->Replace(pChar, clsExp));
}
BooleanExp* AndExp::Copy() const
{
return new AndExp(m_pOperate1->Copy(), m_pOperate2->Copy());
}
#ifndef CONTEXT_H_
#define CONTEXT_H_
#include "VariableExp.h"
class Context
{
public:
bool Lookup(const char* pChar) const;
void Assign(VariableExp* pExp, bool bAssign);
};
#endif // !CONTEXT_H_
#ifndef VARAIABLE_EXP_H_
#define VARAIABLE_EXP_H_
#include "BooleanExp.h"
class VariableExp : public BooleanExp
{
public:
VariableExp(const char* pExp);
virtual ~VariableExp();
virtual bool Evaluate(Context& clsContext);
virtual BooleanExp* Replace(const char* pChar, BooleanExp& clsExp);
virtual BooleanExp* Copy() const;
private:
char* m_pCName;
};
#endif
#include "VariableExp.h"
#include
VariableExp::VariableExp(const char* pExp)
: m_pCName(const_cast(pExp))
{
}
bool VariableExp::Evaluate(Context& clsContext)
{
return clsContext.Lookup(m_pCName);
}
BooleanExp* VariableExp::Replace(const char* pChar, BooleanExp& clsExp)
{
if (strcmp(m_pCName, pChar) == 0)
{
return clsExp.Copy();
}
else
{
return new VariableExp(m_pCName);
}
}
BooleanExp* VariableExp::Copy() const
{
return new VariableExp(m_pCName);
}
相关模式
意图
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
动机
一个聚合对象,如列表(ist),应该提供一种方法让别人可以访问它的元素,而又不需要暴露它的内部结构。此外,针对不同的需求,可能要以不同的方式遍历这个列表。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iquLouxG-1652451824237)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220426221553151.png)]
参与者
效果
代码示例
#ifndef MY_LIST_H_
#define MY_LIST_H_
template
const INT32 DEFAULT_LIST_CAPACITY = 1000;
class MyList
{
public:
MyList(long size = DEFAULT_LIST_CAPACITY);
long Count() const;
Item& Get(long nIndex) const;
~MyList(void);
};
#endif
#ifndef MY_ITERATOR_H_
#define MY_ITERATOR_H_
template
class MyIterator
{
public:
~MyIterator(void);
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual BOOL IsDone() const = 0;
virtual Item CurrentItem() const = 0;
protected:
MyIterator(void);
};
#endif
#ifndef MY_LIST_ITERATOR_H_
#define MY_LIST_ITERATOR_H_
#include "MyIterator.h"
#include
#include
template
class MyListIterator : public MyListIterator-
{
public:
MyListIterator(const MyList
- * pList);
~MyListIterator(void);
virtual void First();
virtual void Next();
virtual void IsDone();
virtual Item CurrentItem() const;
private:
const MyList
- * m_pMyList;
long m_nCurrentItemIndex;
};
template
Item MyListIterator- ::CurrentItem() const
{
if (NULL == m_pMyList)
{
assert(false);
return;
}
if (IsDone())
{
return;
}
return m_pMyList->Get(m_nCurrentItemIndex)
}
template
void MyListIterator- ::IsDone()
{
if (NULL == m_pMyList)
{
assert(false);
return;
}
return m_nCurrentItemIndex >= m_pMyList->Count();
}
template
void MyListIterator- ::First()
{
m_nCurrentItemIndex = 0;
}
template
void MyListIterator- ::Next()
{
m_nCurrentItemIndex++;
}
template
MyListIterator- ::MyListIterator(const MyList
- * pList)
: m_pMyList(pList)
, m_nCurrentItemIndex(0)
{
}
#endif
相关模式
意图
用一个中介对象封装一系列对象的交互。中介者使各对象不需要显示引用,从而使其耦合松散。
动机
面向对象设计鼓励将行为分布到各个对象中。这种分布可能会导致对象间有许多连接。在最坏 的情况下,每个对象都知道其他所有对象。考虑一个图形界面对话框的实现。对话框的窗口组件之间存在依赖关系,例如当一个特定的输入为空时,某个按钮要禁用。因此即便对话框显示相同类型的窗口组件,也不能简单直接复用已有的窗口组件。可以将集体行为封装在一个单独的中介者对象中。中介者统一控制和协调一组对象的交互。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhdj1g6T-1652451824237)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220425215322897.png)]
参与者
效果
代码示例
//Widget.h
#ifndef WIDGET_H_
#define WIDGET_H_
#include "DialogDirector.h"
class Widget
{
public:
Widget(DialogDirector* pDirector);
~Widget(void);
virtual void Changed();
virtual void HandleMouse(MouseEvent& clsEvent);
private:
DialogDirector* m_pDirector;
};
#endif
//Widget.cpp
#include "Widget.h"
#include
#include
Widget::Widget(DialogDirector* pDirector)
: m_pDirector(pDirector)
{
}
Widget::~Widget(void)
{
}
void Widget::Changed()
{
if (NULL == m_pDirector)
{
assert(false);
return;
}
m_pDirector->WidgetChanged(this);
}
//IButton.h
#ifndef IBUTTON_H_
#define IBUTTON_H_
#include "Widget.h"
#include "DialogDirector.h"
class IButton : public Widget
{
public:
IButton(DialogDirector* pDirector);
~IButton(void);
virtual void SetText(const char* pText);
virtual void HandleMouse(MouseEvent& clsEvent);
};
#endif
//IButton.cpp
#ifndef IBUTTON_H_
#define IBUTTON_H_
#include "Widget.h"
#include "DialogDirector.h"
class IButton : public Widget
{
public:
IButton(DialogDirector* pDirector);
~IButton(void);
virtual void SetText(const char* pText);
virtual void HandleMouse(MouseEvent& clsEvent);
};
#endif
//IEntryFiled.h
#ifndef IENTRY_FILED_H_
#define IENTRY_FILED_H_
#include "Widget.h"
#include "DialogDirector.h"
class IEntryFiled : public Widget
{
public:
IEntryFiled(DialogDirector* pDirector);
~IEntryFiled(void);
virtual void SetText(const char* pText);
virtual const char* GetText();
virtual void HandleMouse(MouseEvent& clsEvent);
};
#endif
//IEntryFiled.cpp
#include "IEntryFiled.h"
IEntryFiled::IEntryFiled(DialogDirector* pDirector)
:Widget(pDirector)
{
}
IEntryFiled::~IEntryFiled(void)
{
}
//IListBox.h
#ifndef ILIST_BOX_H_
#define ILIST_BOX_H_
#include "Widget.h"
#include "DialogDirector.h"
#include
using namespace std;
class IListBox : public Widget
{
public:
IListBox(DialogDirector* pDirector);
~IListBox(void);
virtual const char* GetSelection();
virtual void SetList(std::List* pListItem);
virtual void HandleMouse(MouseEvent& clsEvent);
};
#endif
//IListBox.cpp
#include "IListBox.h"
IListBox::IListBox(DialogDirector* pDirector)
:Widget(pDirector)
{
}
IListBox::~IListBox(void)
{
}
//DiaglogDirector.h
#ifndef DIALOG_DIRECTOR_H_
#define DIALOG_DIRECTOR_H_
class Widget;
class DialogDirector
{
public:
~DialogDirector(void);
virtual void ShowDialog();
virtual void WidgetChanged(Widget* pWidget) = 0;
protected:
DialogDirector(void);
virtual void CreateWidgets() = 0;
};
#endif
//DialogDirector.cpp
#include "DialogDirector.h"
DialogDirector::DialogDirector(void)
{
}
DialogDirector::~DialogDirector(void)
{
}
//FontDialogDirector.h
#ifndef FONT_DIALOG_DIRECTOR_H_
#define FONT_DIALOG_DIRECTOR_H_
#include "DialogDirector.h"
#include "IButton.h"
#include "IEntryFiled.h"
#include "IListBox.h"
class FontDialogDirector : public DialogDirector
{
public:
FontDialogDirector(void);
~FontDialogDirector(void);
virtual void WidgetChanged(Widget* pWidget);
protected:
virtual void CreateWidgets();
private:
IButton* m_pOkBtn;
IButton* m_pCancelBtn;
IListBox* m_pFontBox;
IEntryFiled* m_pFontName;
};
#endif
//FontDialogDirector.cpp
#include "FontDialogDirector.h"
#include
FontDialogDirector::FontDialogDirector(void)
{
}
FontDialogDirector::~FontDialogDirector(void)
{
}
void FontDialogDirector::WidgetChanged(Widget* pWidget)
{
if ((NULL == m_pOkBtn) || (NULL == m_pCancelBtn)
|| (NULL == m_pFontBox) || (NULL == m_pFontName))
{
assert(false);
return;
}
if (pWidget == m_pFontBox)
{
m_pFontName->SetText(m_pFontBox->GetSelection());
}
else if (pWidget == m_pOkBtn)
{
}
else if (pWidget == m_pCancelBtn)
{
}
}
void FontDialogDirector::CreateWidgets()
{
m_pOkBtn = new IButton(this);
m_pCancelBtn = new IButton(this);
m_pFontBox = new IListBox(this);
m_pFontName = new IEntryFiled(this);
}
//main.cpp
#include
#include "FontDialogDirector.h"
int main()
{
FontDialogDirector* pDiaglog = new FontDialogDirector();
system("pause");
return 0;
}
相关模式
意图
在不破坏封装的的前提下,捕获一个对象的内部状态,并在对象之外维护这个状态。
动机
有时必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制,而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。但是对象通常封装了其部分或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jO8FuAsM-1652451824238)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220424224128604.png)]
参与者
效果
代码示例
相关模式
意图
定义对象间的一种一对多的依赖,当一个对象的状态改变时,所有依赖于它的对象都得到通知并被自动更新。
动机
对于许多图形用户界面工具箱将用户应用的界面表示与底下的应用数据分离。例如,一个表格对象和一个柱状图可使用不同的表示形式描述同一个应用数据对象的信息。表格对象和柱状图对象相互不知道对方的存在,这样使你可以根据需要单独复用表格或柱状图。但是数据变化后,表格对象和柱状图对象都要根据数据刷新显示。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvrlXzxS-1652451824238)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220420225602763.png)]
参与者
效果
代码示例
//Observer.h
#ifndef OBSERVER_H_
#define OBSERVER_H_
class Subject;
class Observer
{
public:
~Observer(void);
virtual void Update(Subject* pSubject) = 0;
protected:
Observer(void);
};
#endif
//DigitalClock.h
#ifndef DIGITAL_CLOCK_H_
#define DIGITAL_CLOCK_H_
#include "Observer.h"
#include "ClockTimer.h"
#include "IWidget.h"
class DigtalClock : public IWidget, public Observer
{
public:
DigtalClock(ClockTimer* pClockTimer);
~DigtalClock(void);
virtual void Update(Subject* pSubject);
virtual void Draw();
private:
ClockTimer* m_pSubject;
};
#endif
//DigitalClock.pp
#include "DigtalClock.h"
#include
#include
DigtalClock::DigtalClock(ClockTimer* pClockTimer)
: m_pSubject(pClockTimer)
{
m_pSubject->Attach(this);
}
DigtalClock::~DigtalClock(void)
{
m_pSubject->Detach(this);
}
void DigtalClock::Update(Subject* pSubject)
{
if (NULL == pSubject || NULL == m_pSubject)
{
assert(false);
return;
}
if (m_pSubject == pSubject)
{
Draw();
}
}
void DigtalClock::Draw()
{
if (NULL == m_pSubject)
{
assert(false);
return;
}
int hour = m_pSubject->GetHour();
int minute = m_pSubject->GetMinute();
//.....
}
//AnalogClock.h
#ifndef ANALOG_CLOCK_H_
#define ANALOG_CLOCK_H_
#include "Observer.h"
#include "ClockTimer.h"
#include "IWidget.h"
class AnalogClock : public IWidget, public Observer
{
public:
AnalogClock(ClockTimer* pClockTimer);
~AnalogClock(void);
virtual void Update(Subject* pSubject);
virtual void Draw();
private:
ClockTimer* m_pSubject;
};
#endif
//AnalogClock.cpp
#include "AnalogClock.h"
#include
#include
AnalogClock::AnalogClock(ClockTimer* pClockTimer)
: m_pSubject(pClockTimer)
{
m_pSubject->Attach(this);
}
AnalogClock::~AnalogClock(void)
{
m_pSubject->Detach(this);
}
void AnalogClock::Update(Subject* pSubject)
{
if (NULL == pSubject || NULL == m_pSubject)
{
assert(false);
return;
}
if (m_pSubject == pSubject)
{
Draw();
}
}
void AnalogClock::Draw()
{
if (NULL == m_pSubject)
{
assert(false);
return;
}
int hour = m_pSubject->GetHour();
int minute = m_pSubject->GetMinute();
//.....
}
//Subject.h
#ifndef SUBJECT_H_
#define SUBJECT_H_
#include "Observer.h"
#include
#include
class Subject
{
public:
~Subject(void);
virtual void Attach(Observer* pObserver);
virtual void Detach(Observer* pObserver);
virtual void Notify();
protected:
Subject(void);
private:
std::list m_listObserver;
};
#endif
//Subject.cpp
#include "Subject.h"
#include
#include
#include "Observer.h"
Subject::Subject(void)
{
}
Subject::~Subject(void)
{
}
void Subject::Attach(Observer* pObserver)
{
if (NULL == pObserver)
{
assert(false);
return;
}
m_listObserver.push_back(pObserver);
}
void Subject::Detach(Observer* pObserver)
{
if (NULL == pObserver)
{
assert(false);
return;
}
m_listObserver.remove(pObserver);
}
void Subject::Notify()
{
std::list::iterator itor = m_listObserver.begin();
for (; itor != m_listObserver.end(); ++itor)
{
(*itor)->Update(this);
}
}
//ClockTimer.h
#ifndef CLOCK_TIMER_H_
#define CLOCK_TIMER_H_
#include "Subject.h"
class ClockTimer : public Subject
{
public:
ClockTimer(void);
~ClockTimer(void);
virtual int GetHour(){return 0;};
virtual int GetMinute(){return 0;};
virtual int GetSecond(){return 0;};
void Tick();
};
#endif
//ClockTimer.cpp
#include "ClockTimer.h"
ClockTimer::ClockTimer(void)
{
}
ClockTimer::~ClockTimer(void)
{
}
void ClockTimer::Tick()
{
Subject::Notify();
}
//IWieget.h
#ifndef IWIDGET_H_
#define IWIDGET_H_
class IWidget
{
public:
IWidget(void);
~IWidget(void);
virtual void Draw();
};
#endif
//IWidget.cp
#include "IWidget.h"
IWidget::IWidget(void)
{
}
IWidget::~IWidget(void)
{
}
void IWidget::Draw()
{
}
//main.cpp
#include "ClockTimer.h"
#include "AnalogClock.h"
#include "DigtalClock.h"
int main()
{
ClockTimer* pTimer = new ClockTimer;
AnalogClock* pAngleClock = new AnalogClock(pTimer);
DigtalClock* pDigitalClock = new DigtalClock(pTimer);
system("pause");
return 0;
}
相关模式
意图
允许一个对象在其内部状态改变时改变它的行为。
动机
考虑一个表示网络连接的类TCPConnection。一个网络连接会有:连接已建立、正在监听、连接已关闭。当一个TCPConnection对象收到其他对象的请求时,根据自身的当前状态做出不同的反应。状态模式为不同的状态提供一个抽象类,表示网络的连接状态。TCPState类为各表示不同的操作状态的子类声明了一个公共接口。TCPState子类实现与特定转态相关的行为。
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maZxi15k-1652451824238)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220418223705908.png)]
参与者
效果
代码示例
//TCPState.h
#ifndef TCP_STATE_H_
#define TCP_STATE_H_
class TCPConnection;
class TCPOctetStream;
class TCPState
{
public:
TCPState();
~TCPState();
virtual void Transmit(TCPConnection* pConnection, TCPOctetStream* pOctetStream){};
virtual void ActiveOpen(TCPConnection* pCOnnection){};
virtual void PassiveOpen(TCPConnection* pConnection){};
virtual void Close(TCPConnection* pConnection){};
virtual void Synchronize(TCPConnection* pConnection){};
virtual void Acknowledge(TCPConnection* pConnection){};
virtual void Send(TCPConnection* pConnection){};
protected:
void ChangeState(TCPConnection* pConnection, TCPState* pState);
};
#endif
//TcpState.cpp
#include "TCPState.h"
#include "TCPConnection.h"
TCPState::TCPState(/* args */)
{
}
TCPState::~TCPState()
{
}
void TCPState::ChangeState(TCPConnection* pConnection, TCPState* pState)
{
if (0 != pConnection || 0 != pState)
{
pConnection->ChangeState(pState);
}
}
//TCPClose.h
#ifndef TCP_CLOSED_H_
#define TCP_CLOSED_H_
#include "TCPState.h"
class TCPClosed : public TCPState
{
public:
TCPClosed(/* args */);
~TCPClosed();
virtual void ActiveOpen(TCPConnection* pConnection);
virtual void PassiveOpen(TCPConnection* pConnection);
};
#endif
//TCPClose.cpp
#include "TCPClosed.h"
#include "TCPConnection.h"
#include "TCPEstablished.h"
#include "TCPListen.h"
TCPClosed::TCPClosed(/* args */)
{
}
TCPClosed::~TCPClosed()
{
}
void TCPClosed::ActiveOpen(TCPConnection* pConnection)
{
if (0 != pConnection)
{
/* code */
TCPEstablished* pEstablishend = new TCPEstablished();
ChangeState(pConnection, pEstablishend);
}
}
void TCPClosed::PassiveOpen(TCPConnection* pConnection)
{
if (0 != pConnection)
{
/* code */
TCPListen* pListen = new TCPListen();
ChangeState(pConnection, pListen);
}
}
//TCPConnection.h
#ifndef TCP_CONNECTION_H_
#define TCP_CONNECTION_H_
class TCPOctetStream;
class TCPState;
class TCPConnection
{
public:
TCPConnection(/* args */);
~TCPConnection();
void ActiveOpen();
void PassiveOpen();
void Close();
void Send();
void Ackonwledge();
void Synchronize();
void ProcessOctet(TCPOctetStream* pOctetStream);
private:
friend class TCPState;
void ChangeState(TCPState* pState);
private:
TCPState* m_pState;
};
#endif
//TCPConnection.cpp
#include "TCPConnection.h"
#include "TCPState.h"
#include "TCPClosed.h"
TCPConnection::TCPConnection()
{
m_pState = new TCPClosed();
}
TCPConnection::~TCPConnection()
{
}
void TCPConnection::ChangeState(TCPState *pState)
{
if (0 != m_pState)
{
/* code */
delete m_pState;
m_pState = 0;
}
if (0 != pState )
{
m_pState = pState;
}
}
void TCPConnection::ActiveOpen()
{
if (0 != m_pState)
{
/* code */
m_pState->ActiveOpen(this);
}
}
void TCPConnection::PassiveOpen()
{
if (0 != m_pState)
{
/* code */
m_pState->PassiveOpen(this);
}
}
void TCPConnection::Close()
{
if (0 != m_pState)
{
/* code */
m_pState->Close(this);
}
}
void TCPConnection::Send()
{
if (0 != m_pState)
{
/* code */
m_pState->Send(this);
}
}
void TCPConnection::Ackonwledge()
{
if (0 != m_pState)
{
/* code */
m_pState->Acknowledge(this);
}
}
void TCPConnection::Synchronize()
{
if (0 != m_pState)
{
/* code */
m_pState->Synchronize(this);
}
}
void TCPConnection::ProcessOctet(TCPOctetStream* pOctetStream)
{
}
//TCPEstablished.h
#ifndef TCP_ESTABLISHED_H_
#define TCP_ESTABLISHED_H_
#include "TCPState.h"
class TCPEstablished : public TCPState
{
public:
TCPEstablished(/* args */);
~TCPEstablished();
virtual void Transmit(TCPConnection* pConnection, TCPOctetStream* pOctetStream);
virtual void Close(TCPConnection* pConnection);
};
#endif
//TCPEstablished.cpp
#include "TCPEstablished.h"
#include "TCPListen.h"
TCPEstablished::TCPEstablished(/* args */)
{
}
TCPEstablished::~TCPEstablished()
{
}
void TCPEstablished::Transmit(TCPConnection* pConnection, TCPOctetStream* pOctetStream)
{
}
void TCPEstablished::Close(TCPConnection* pConnection)
{
TCPListen* pListen = new TCPListen();
ChangeState(pConnection, pListen);
}
//TCPListen.h
#ifndef TCP_LISTEN_H_
#define TCP_LISTEN_H_
#include "TCPState.h"
class TCPListen : public TCPState
{
public:
TCPListen(/* args */);
~ TCPListen();
virtual void Send(TCPConnection* pConnection);
};
#endif
//TCPLisen.cpp
#include "TCPListen.h"
#include "TCPConnection.h"
#include "TCPEstablished.h"
TCPListen::TCPListen()
{
}
TCPListen::~TCPListen()
{
}
void TCPListen::Send(TCPConnection* pConnection)
{
if (0 != pConnection)
{
/* code */
TCPEstablished* pEstablished = new TCPEstablished();
ChangeState(pConnection, pEstablished);
}
}
//main.cpp
#include "TCPConnection.h"
#include
int main()
{
TCPConnection* pConnection = new TCPConnection();
pConnection->ActiveOpen();
pConnection->Send();
return 0;
}
相关模式
意图
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法可以独立于它的客户而变化,隔离算法变化与客户端代码。
动机
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uEYCy2r8-1652451824239)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220408073806848.png)]
参与者
效果
代码示例
//CashSuper.h
#ifndef STRATEGY_H_
#define STRATEGY_H_
class CashSuper
{
public:
CashSuper();
~CashSuper();
virtual double AcceptCash(double fMoney) = 0;
};
class CashNormal : public CashSuper
{
public:
public:
CashNormal();
~CashNormal();
virtual double AcceptCash(double fMoney) { return fMoney; };
};
class CashRebate : public CashSuper
{
public:
CashRebate(double fMoenyRebate);
~CashRebate();
virtual double AcceptCash(double fMoney) { return fMoney * m_fMoneyRebate; };
private:
double m_fMoneyRebate;
};
class CashReturn : public CashSuper
{
public:
CashReturn(double fMoneyConditon, double fMoneyReturn);
~CashReturn();
virtual double AcceptCash(double fMoney);
private:
double m_fMoneyCondition;
double m_fMoneyReturn;
};
#endif
//CashSuper.cpp
#include "CashSuper.h"
CashSuper::CashSuper()
{
}
CashSuper::~CashSuper()
{
}
CashNormal::CashNormal()
{
}
CashNormal::~CashNormal()
{
}
CashRebate::CashRebate(double fMoenyRebate)
: m_fMoneyRebate(fMoenyRebate)
{
}
CashRebate::~CashRebate()
{
}
CashReturn::CashReturn(double fMoneyConditon, double fMoneyReturn)
: m_fMoneyCondition(fMoneyConditon)
, m_fMoneyReturn(fMoneyReturn)
{
}
CashReturn::~CashReturn()
{
}
double CashReturn::AcceptCash(double fMoney)
{
double fResultMoney = fMoney;
if (fMoney >= m_fMoneyCondition)
{
fResultMoney = fMoney - m_fMoneyReturn;
}
return fResultMoney;
}
//Context.h
#ifndef CASH_CONTEXT_H_
#define CASH_CONTEXT_H_
class CashSuper;
enum CashType
{
CashType_Start,
CashType_Normal = CashType_Start,
CashType_Rebate,
CashType_Return,
CashType_Max,
};
class CashContext
{
public:
CashContext(CashType eCashType);
~CashContext();
public:
double GetResultMoney(double fMoney);
private:
void CreateCashAlgorithm(CashType eType);
private:
CashSuper* m_pCashSuper;
};
#endif
//Context.cpp
#include "CashContext.h"
#include "CashSuper.h"
CashContext::CashContext(CashType eCashType)
: m_pCashSuper(0)
{
CreateCashAlgorithm(eCashType);
}
CashContext::~CashContext()
{
if (0 != m_pCashSuper)
{
delete m_pCashSuper;
m_pCashSuper = 0;
}
}
double CashContext::GetResultMoney(double fMoney)
{
if (0 == m_pCashSuper)
{
return 0;
}
return m_pCashSuper->AcceptCash(fMoney);
}
void CashContext::CreateCashAlgorithm(CashType eType)
{
switch (eType)
{
case CashType_Normal:
m_pCashSuper = new CashNormal();
break;
case CashType_Rebate:
m_pCashSuper = new CashRebate(0.8);
break;
case CashType_Return:
m_pCashSuper = new CashReturn(549.4, 12.54);
break;
default:
break;
}
}
//客户端代码
#include "CashContext.h"
#include "CashSuper.h"
#include
using namespace std;
int main()
{
CashContext* pCashContext = new CashContext(CashType_Rebate);
double fPrice = 6867896.98;
cout << "根据当前策略,本次实际收钱:" << pCashContext->GetResultMoney(fPrice) << endl;
return 0;
}
相关模式
意图
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。在子类中根据需要,重定义该算法的某些特定步骤。
动机
适用性
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1v9I3otI-1652451824239)(C:\Users\15497\AppData\Roaming\Typora\typora-user-images\image-20220413230255265.png)]
参与者
效果
模板方法是一种代码复用的基本技术。它们在类库中尤为重要,提取类库中的公共行为。
模板方法调用下列类型的操作:
代码示例
//LayoutBase.h
#ifndef LAYOUT_BASE_H_
#define LAYOUT_BASE_H_
class LayoutBase
{
public:
LayoutBase();
~LayoutBase();
public:
//TemplateMethod
void UpdateLayout();
//两个钩子操作
virtual void CreateLeftLayout() {};
virtual void CreateRightLayout() {};
};
#endif
//LayoutBase.cpp
#include "LayoutBase.h"
#include
using namespace std;
LayoutBase::LayoutBase()
{
}
LayoutBase::~LayoutBase()
{
}
void LayoutBase::UpdateLayout()
{
CreateLeftLayout();
CreateRightLayout();
cout << "Combine left layout and right layuout! << finish layout" << endl;
}
//LayoutPad.h
#ifndef LAYOUT_PAD_H_
#define LAYOUT_PAD_H_
#include "LayoutBase.h"
class LayoutPad : public LayoutBase
{
public:
LayoutPad();
~LayoutPad();
protected:
virtual void CreateLeftLayout();
virtual void CreateRightLayout();
};
#endif
//LayoutPad.cpp
#include "LayoutPad.h"
#include "LayoutPad.h"
#include
using namespace std;
LayoutPad::LayoutPad()
{
}
LayoutPad::~LayoutPad()
{
}
void LayoutPad::CreateLeftLayout()
{
cout << "CreateLeftLayout in pad!" << endl;
}
void LayoutPad::CreateRightLayout()
{
cout << "CreateRightLayout in pad!" << endl;
}
//LayoutPhone.h
#ifndef LAYOUT_PHONE_H_
#define LAYOUT_PHONE_H_
#include "LayoutBase.h"
class LayoutPhone : public LayoutBase
{
public:
LayoutPhone();
~LayoutPhone();
protected:
virtual void CreateLeftLayout();
virtual void CreateRightLayout();
};
#endif
//LayoutPhone.cpp
#include "LayoutPhone.h"
#include
using namespace std;
LayoutPhone::LayoutPhone()
{
}
LayoutPhone::~LayoutPhone()
{
}
void LayoutPhone::CreateLeftLayout()
{
cout << "CreateLeftLayout in phone!" << endl;
}
void LayoutPhone::CreateRightLayout()
{
cout << "CreateLeftLayout in phone!" << endl;
}
//main.cpp
#include
#include "LayoutPad.h"
#include "LayoutPhone.h"
#include "LayoutBase.h"
using namespace std;
int main()
{
//在pad客户端代码
LayoutBase* pLayout = new LayoutPad();
pLayout->UpdateLayout();
//在phone客户端
LayoutBase* pLayout = new LayoutPhone();
pLayout->UpdateLayout();
return 0;
}
相关模式
意图
表示作用于某对象结构中各元素的操作。使你可以在不改变各元素类的前提下,定义作用于这些元素的新操作。
动机
适用性
在下列情况下使用Visitor模式:
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MaRc1W0u-1652451824244)()]
参与者
效果
代码示例
//visitor.h
#ifndef VISITOR_H_
#define VISITOR_H_
#include "Man.h"
#include "Woman.h"
class Man;
class Woman;
class Visitor
{
public:
Visitor(void);
virtual ~Visitor(void);
public:
virtual void VisitMan(Man* pMan) = 0;
virtual void VisitWoman(Woman* pWoman) = 0;
};
#endif
//HairStyleVisitor.h
#ifndef HAIR_STYLE_VISITOR_H_
#define HAIR_STYLE_VISITOR_H_
#include "Visitor.h"
class HairStyleVisitor : public Visitor
{
public:
HairStyleVisitor(void);
virtual ~HairStyleVisitor(void);
public:
virtual void VisitMan(Man* pMan);
virtual void VisitWoman(Woman* pWoman);
};
#endif
//HairStyleVisitor.cpp
#include "HairStyleVisitor.h"
#include
#include
#include
using namespace std;
HairStyleVisitor::HairStyleVisitor(void)
{
}
HairStyleVisitor::~HairStyleVisitor(void)
{
}
void HairStyleVisitor::VisitMan(Man* pMan)
{
cout << "Man Like Short hair more!" << endl;
}
void HairStyleVisitor::VisitWoman(Woman* pWoman)
{
cout << "Woman Like Long hair more!" << endl;
}
//HealthVisitor.h
#ifndef HEALTH_VISITOR_H_
#define HEALTH_VISITOR_H_
#include "Visitor.h"
class HealthVisitor : public Visitor
{
public:
HealthVisitor(void);
virtual ~HealthVisitor(void);
public:
virtual void VisitMan(Man* pMan);
virtual void VisitWoman(Woman* pWoman);
};
#endif
//HealthVisitor.cpp
#include "HealthVisitor.h"
#include
#include
#include
using namespace std;
HealthVisitor::HealthVisitor(void)
{
}
HealthVisitor::~HealthVisitor(void)
{
}
void HealthVisitor::VisitMan(Man* pMan)
{
cout << "Man focus on male sick!" << endl;
}
void HealthVisitor::VisitWoman(Woman* pWoman)
{
cout << "Woman focus on femal sick!" << endl;
}
//Person.h
#ifndef PERSON_H_
#define PERSON_H_
class Visitor;
class Person
{
public:
Person(void);
virtual ~Person(void);
public:
virtual void Accept(Visitor* pVisitor) = 0;
};
#endif
//Man.h
#ifndef MAN_H_
#define MAN_H_
#include "Visitor.h"
#include "Person.h"
class Person;
class Visitor;
class Man : public Person
{
public:
Man(void);
virtual ~Man(void);
public:
virtual void Accept(Visitor* pVisitor);
};
#endif
//Man.cpp
#include "Man.h"
#include
#include
Man::Man(void)
{
}
Man::~Man(void)
{
}
void Man::Accept(Visitor* pVisitor)
{
if (NULL == pVisitor)
{
assert(false);
return;
}
pVisitor->VisitMan(this);
}
//Woman.h
#ifndef WOMAN_H_
#define WOMAN_H_
#include "Person.h"
#include "Visitor.h"
class Person;
class Woman : public Person
{
public:
Woman(void);
virtual ~Woman(void);
public:
virtual void Accept(Visitor* pVisitor);
};
#endif
//Woman.cpp
#include "Woman.h"
#include
#include
Woman::Woman(void)
{
}
Woman::~Woman(void)
{
}
void Woman::Accept(Visitor* pVisitor)
{
if (NULL == pVisitor)
{
assert(false);
return;
}
pVisitor->VisitWoman(this);
}
//Collegue.h
#ifndef COLLEGUE_H_
#define COLLEGUE_H_
#include "Visitor.h"
#include "Person.h"
#include
#include
class Collegue
{
public:
public:
Collegue(void);
~Collegue(void);
public:
void Accept(Visitor* pVisitor);
void AddCollegue(Person* pPerson);
void RemoveCollegue(Person* pPerson);
private:
std::vector m_vecCollegue;
};
#endif
//Collegue.cpp
#include "Collegue.h"
#include "Visitor.h"
#include
#include
Collegue::Collegue(void)
{
}
Collegue::~Collegue(void)
{
}
void Collegue::Accept(Visitor* pVisitor)
{
if (NULL == pVisitor)
{
assert(false);
return;
}
std::vector::iterator itor = m_vecCollegue.begin();
for (; itor != m_vecCollegue.end(); ++itor)
{
(*itor)->Accept(pVisitor);
}
}
void Collegue::AddCollegue(Person* pPerson)
{
if (NULL == pPerson)
{
assert(false);
return;
}
m_vecCollegue.push_back(pPerson);
}
void Collegue::RemoveCollegue(Person* pPerson)
{
if (NULL == pPerson)
{
assert(false);
return;
}
std::vector::iterator itor = m_vecCollegue.begin();
while(itor != m_vecCollegue.end())
{
if (*itor == pPerson)
{
break;;
}
++itor;
}
m_vecCollegue.erase(itor);
}
//Client.cpp(客户端代码)
#include "HairStyleVisitor.h"
#include "HealthVisitor.h"
#include "Man.h"
#include "Person.h"
#include "Visitor.h"
#include "Woman.h"
using namespace std;
enum CollegueNo
{
Collegue_Start,
CollegueNo_1 = Collegue_Start,
CollegueNo_2 ,
CollegueNo_3 ,
CollegueNo_4 ,
CollegueNo_Max,
};
enum CollegueGender
{
CollegueGender_Start,
CollegueGender_Man = CollegueGender_Start,
CollegueGender_Woman,
CollegueGender_Max,
};
struct CollegueInfo
{
public:
CollegueNo m_eCollegueNo;
CollegueGender m_eCollegueGender;
};
static CollegueInfo sCollegueInfos [] =
{
{CollegueNo_1, CollegueGender_Man},
{CollegueNo_2, CollegueGender_Woman},
{CollegueNo_3, CollegueGender_Man},
{CollegueNo_4, CollegueGender_Woman},
};
enum CollegueInfoParser
{
CollegueInfoParser_Start,
CollegueInfoParser_HairStyle = CollegueInfoParser_Start,
CollegueInfoParser_Health,
CollegueInfoParser_Max,
};
void InitCollegueInfo(std::vector& vecCollegue)
{
vecCollegue.resize(Collegue::CollegueNo_Max);
for (int nIndex = 0 ; nIndex < ARRAYSIZE(sCollegueInfos); nIndex++)
{
Person* pPerson = NULL;
if (sCollegueInfos[nIndex].m_eCollegueGender == Collegue::CollegueGender_Woman)
{
pPerson = new Woman();
}
else
{
pPerson = new Man();
}
vecCollegue.push_back(pPerson);
}
}
void ReleaseCollegueInfo(std::vector& vecCollegues)
{
if (vecCollegues.empty())
{
return;
}
std::vector::iterator itor = vecCollegues.begin();
for (; itor != vecCollegues.end(); ++itor)
{
delete (*itor);
(*itor) = NULL;
}
}
int main(void)
{
std::vector vecCollegues;
InitCollegueInfo(vecCollegues);
Collegue* pCollegue = new Collegue();
std::vector::iterator itor = vecCollegues.begin();
for (; itor != vecCollegues.end(); ++itor)
{
pCollegue->AddCollegue(*itor);
}
std::map mapCollegueInfoProcessor;
mapCollegueInfoProcessor[CollegueInfoParser_HairStyle] = new HairStyleVisitor();
mapCollegueInfoProcessor[CollegueInfoParser_Health] = new HealthVisitor();
pCollegue->Accept(mapCollegueInfoProcessor[CollegueInfoParser_HairStyle]);
pCollegue->Accept(mapCollegueInfoProcessor[CollegueInfoParser_Health]);
ReleaseCollegueInfo(vecCollegues);
delete mapCollegueInfoProcessor[CollegueInfoParser_HairStyle];
mapCollegueInfoProcessor[CollegueInfoParser_HairStyle] = NULL;
delete mapCollegueInfoProcessor[CollegueInfoParser_Health];
mapCollegueInfoProcessor[CollegueInfoParser_Health] = NULL;
return 0;
}
相关模式
类在编译的时候可以确定的差异,对象在运行时明确。
白箱复用:通过生成子类的复用。
黑箱复用:通过组装或对象组合的复用。