1.Strategy 策略模式
class Context: //调用策略的类
{
Context(Strategy *pStrategy)
{
Strategy = Strategy;
}
void ContextInterface(); //调用m_pStrategy的AlgorithmInterface
{
m_pStrategy->AlgorithmInterface();
}
private:
Strategy *Strategy;
}
//策略基类
class Strategy
{
virtual void AlgorithmInterface() = 0;
}
//策略1
class Strategy1:public Strategy
{
void AlgorithmInterface()
{
//,,,,,,,,,,,,,
}
}
class Strategy2:public Strategy
{
void AlgorithmInterface()
{
//,,,,,,,,,,,,,
}
}
int main()
{CContext *pContext = new CContext(new Strategy1());
pContext->ContextInterface();delete pContext;
CContext *pContext1 = new CContext(new Strategy2());
pContext1->ContextInterface();delete pContext1;
}
简单工厂模式是实现对象的多样性,而策略模式适合类中的成员以方法为主; 简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
2.Visitor Pattern)
如何扩展一个现有的类层次结构来实现新行为?一般的方法是给类添加新的方法。但是万一新行为和现有对象模型不兼容怎么办?还有,类层次结构设计人员可能无法预知
以后开发过程中将会需要哪些功能。以及,如果已有的类层次结构不允许修改代码,怎么能扩展行为呢?
答案是在类层次结构设计中使用访问者模式。
class Visitor;
class Element
{
public:
virtual ~Element(){}
virtual void Accept(Visitor &rVisitor) = 0;
protected:
Element(){}
};
class ConcreateElementA
: public Element
{
public:
virtual ~ConcreateElementA() {}
virtual void Accept(Visitor &rVisitor) {rVisitor.VisitConcreateElementA (this);}
};
class ConcreateElementB
: public Element
{
public:
virtual ~ConcreateElementB() {}
virtual void Accept(Visitor &rVisitor){rVisitor.VisitConcreateElementB(this);}
};
class Visitor
{
public:
Visitor(){}
virtual ~Visitor(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA) = 0;
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB) = 0;
};
class ConcreateVisitorA
: public Visitor
{
public:
virtual ~ConcreateVisitorA(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
{//处理pConcreateElementA中信息
std::cout << "VisitConcreateElementA By ConcreateVisitorA\n";
}
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB)
{//处理pConcreateElementB中信息
std::cout << "VisitConcreateElementB By ConcreateVisitorA\n";
}
};
class ConcreateVisitorB
: public Visitor
{
public:
virtual ~ConcreateVisitorB(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
{//处理pConcreateElementA中信息
std::cout << "VisitConcreateElementA By ConcreateVisitorB\n";
}
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB)
{//处理pConcreateElementA中信息
std::cout << "VisitConcreateElementB By ConcreateVisitorB\n";
}
};
int main()
{
Visitor *pVisitorA = new ConcreateVisitorA();
Element *pElementA = new ConcreateElementA();
pElementA->Accept(*pVisitorA);
Visitor *pVisitorB = new ConcreateVisitorB();
Element *pElementB = new ConcreateElementB();
pElementB->Accept(*pVisitorB);
}
3.State模式
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的
处理操作的问题,而这样的问题,大部分人是采用switch-case语句进行处理的,
这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代
码进行编译.State模式采用了对这些不同的状态进行封装的方式处理这类问题,
当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责
任交给了具体的状态类去负责.
class State;
class Context
{
public:
Context(State* pState)
{pConcreateStateA = new ConcreateStateA();
pConcreateStateA ->SetContext(this);pConcreateStateB = new ConcreateStateB();
pConcreateStateB ->SetContext(this);
}
~Context()
{
delete pConcreateStateA ;void RequestA()
{
m_pState->HandleA(this);
}
void RequestB()
{
m_pState->HandleB(this);
}
void ChangeState(State *pState)
{
m_pState = pState;
}
private:
State *m_pState;
};
class State
{
public:
virtual ~State(){}
void SetContext(CContext *pContext);virtual void HandleA(Context* pContext) = 0;
virtual void HandleB(Context* pContext) = 0;};
class ConcreateStateA : public State
{
public:
void HandleA(Context* pContext)
{
cout<<"处理A"<<endl;
}
void HandleB(Context* pContext){
pContext->ChangeState(CContext::pConcreateStateB);
pContext->RequestB();
pContext->ChangeState(CContext::pConcreateStateA);}
};
class ConcreateStateB: public State
{
public:
void HandleA(Context* pContext)
{
pContext->ChangeState(CContext::pConcreateStateA);
pContext->RequestA();
pContext->ChangeState(CContext::pConcreateStateB);}
void HandleB(Context* pContext){
cout<<"处理B"<<endl;
}
};
int main()
{CContext context;
ConcreateStateA closeingState;
closeingState.SetContext(&context);
context.SetLiftState(&closeingState);
context.RequestA();
context.RequestB();
}
4.TemplateMethod模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
class AbstractClass
{
public:
AbstractClass(){}
virtual ~AbstractClass(){}
// 这个函数中定义了算法的轮廓
void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
}
protected:
// 纯虚函数,由派生类实现之
virtual void PrimitiveOperation1() = 0;
virtual void PrimitiveOperation2() = 0;
};
// 继承自AbstractClass,实现算法
class ConcreateClass
: public AbstractClass
{
public:
ConcreateClass(){}
virtual ~ConcreateClass(){}
protected:
virtual void PrimitiveOperation1();
virtual void PrimitiveOperation2();
};
5.工厂模式优缺点
简单工厂具有的优点,解决了简单工厂的修改不能关闭的问题。系统新增产品,新增一个产品工厂即可,对抽象工厂不受影响。
缺点:对于创建不同系列的产品无能为力适用性。
6.抽象工厂模式
工厂模式的分析比较 现在可以和工厂模式对比一下,抽象工厂返回的接口不再是产品A和产品B的共同基类Product了,而是产品A、产品B基类(在工厂模式中它们为具体
实现 类,这里变成了基类)了。此时工厂的抽象和简单工厂中的工厂方法也很类似,就是这些特征区使其别于工厂模式而变成抽象工厂模式了,因此抽象工厂解决的是创 建
一系列有共同风格的产品(鲁菜还是粤菜),而工厂方法模式解决的创建有共同特征的一系列产品(红烧肉、清蒸鱼它们都是食物)。当然简单工厂的缺陷在抽象 工厂中又
再次出现了,我要新增加一个产品,工厂抽象接口就要改变了。因此抽象工厂并不比工厂模式完美,只不过是各自的适用领域不同而已。其实,这里如果把 抽象工厂模式的
接口返回产品A和产品B的共同基类(工厂模式返回的参数),你会发现,奇怪这个模式怎么这么眼熟,它不是恰恰退化成工厂模式了。
//单核
class SingleCore
{
public:
virtual void Show() = 0;
};
class SingleCoreA: public SingleCore
{
public:
void Show() { cout<<"Single Core A"<<endl; }
};
class SingleCoreB :public SingleCore
{
public:
void Show() { cout<<"Single Core B"<<endl; }
};
//多核
class MultiCore
{
public:
virtual void Show() = 0;
};
class MultiCoreA : public MultiCore
{
public:
void Show() { cout<<"Multi Core A"<<endl; }
};
class MultiCoreB : public MultiCore
{
public:
void Show() { cout<<"Multi Core B"<<endl; }
};
//工厂
class CoreFactory
{
public:
virtual SingleCore* CreateSingleCore() = 0;
virtual MultiCore* CreateMultiCore() = 0;
};
//工厂A,专门用来生产A型号的处理器
class FactoryA :public CoreFactory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreA(); }
MultiCore* CreateMultiCore() { return new MultiCoreA(); }
};
//工厂B,专门用来生产B型号的处理器
class FactoryB : public CoreFactory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreB(); }
MultiCore* CreateMultiCore() { return new MultiCoreB(); }
};
void main()
{
CoreFactory* pCoreFactoryA = new FactoryA;
SingleCore* pSingleCoreA = pCoreFactoryA->CreateSingleCore();
pSingleCoreA->Show();
CoreFactory* pCoreFactoryB = new FactoryB;
SingleCore* pSingleCoreA1 = pCoreFactoryB->CreateSingleCore();
pSingleCoreA1->Show();
}
7.Build模式
// 虚拟基类,是所有Builder的基类,提供不同部分的构建接口函数
class Builder
{
public :
Builder() {} ;
virtual ~ Builder() {}
// 纯虚函数,提供构建不同部分的构建接口函数
virtual void BuilderPartA() = 0 ;
virtual void BuilderPartB() = 0 ;
} ;
// Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
class ConcreateBuilder1 : public Builder
{
public :
ConcreateBuilder1() {}
virtual ~ ConcreateBuilder1() {}
virtual void BuilderPartA();
virtual void BuilderPartB();
} ;
// 使用Builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
// 这个不同的实现通过不同的Builder派生类来实现,存有一个Builder的指针,通过这个来
// 实现多态调用
class Director
{
public :
Director(Builder * pBuilder);
~ Director();
void Construct()
{pBuilder->BuilderPartA();
pBuilder->BuilderPartB();private :
Builder * m_pBuilder;
} ;
8.原型模式优点:
1、可以灵活的存在程序运行时刻增加和删除产品
2、在不定义一个新类的前提下,通过为一个对象变量指定值就可以有效的定义新类别的对象
3、可以利用该模式使得能实现用类动态配置应用的操作
4,原型模式实现的关键就是实现Clone函数,对于C++来说,其实就是拷贝构造函数,需实现深拷贝,下面给出一种实现。
class Prototype
{
public:
Prototype(){}
virtual ~Prototype(){}
virtual Prototype* Clone() = 0;
};
// 派生自Prototype,实现Clone方法
class ConcreatePrototype1 : public Prototype
{
public:
ConcreatePrototype1();
ConcreatePrototype1(const ConcreatePrototype1&);
virtual ~ConcreatePrototype1();
virtual Prototype* Clone() {new ConcreatePrototype1(*this)}
};
int main()
{
Prototype *r1 = new ConcreatePrototype1();
Prototype *r3 = r1->Clone(); delete r1;delete r3;//深拷贝所以对r3无影响
}
9.单例模式
优点
1、对系统内唯一的实习进行受访控制,通过该模式创建此唯一实例,使其对整个系统提供这一实例,不但保证系统逻辑上的正确简洁明了性,也降低了系统由于人为操作失
误造成的多次实例化该对象的危险性;
2、该模式对全局变量的改进,避免了存储唯一实例的全局变量对整个系统命名空间的污染
3、该模式适用性强,不但可以适用于任何类,也可以进行跨平台操作
4、加入同步机制后,可以保证系统线程安全,增加系统的安全性
缺点
1、初次设计Singleton类时不易,尤其是对static函数,同步机制编程等使用不太清楚的程序员,但该类的可复制性比较强,可以从其他程序中拷贝以后的Singleton类以弥补
该缺点
2、一旦使用了该模式,利用Singleton创建了一个对象后,没有办法取消Singleton的责任,即不能销毁它
class Singleton
{
public:
Singleton(){};
//virtual ~Singleton(){};
virtual ~Singleton();
// 静态成员函数,提供全局访问的接口
static Singleton* GetInstancePtr();
static Singleton GetInstance();
void Test();
private:
// 静态成员变量,提供全局惟一的一个实例
static Singleton* m_pStatic;
};
10.Memento(备忘录)模式
优缺点
Memento模式有以下这些优缺点:
1、保持封装边界 使用备忘录可以避免暴露一些只应由原发器管理却又必须存储在原发器之外的信息。该模式把可能很复杂的Originator内部信息对其他对象屏蔽起来,从
而保持了封装边界。
2、它简化了原发器 在其他的保持封装性的设计中,Originator负责保持客户请求过的内部状态版本。这就把所有存储管理的重任交给了Originator。让客户管理它们请求
的状态将会简化Originator,并且使得客户工作结束时无需通知原发器。
3、使用备忘录可能代价很高 如果原发器在生成备忘录时必须拷贝并存储大量的信息,或者客户非常频繁地创建备忘录和恢复原发器状态,可能会导致非常大的开销。除
非封装和恢复Originator状态的开销不大,否则该模式可能并不合适。
4、维护备忘录的潜在代价 管理器负责删除它所维护的备忘录。然而,管理器不知道备忘录中有多少个状态。因此当存储备忘录时,一个本来很小的管理器,可能会产生
大量的存储开销。
11.观察者模式
前几天,刚写的一个软件崩溃了。跟踪发现是下面函数的问题:
void CSubject::OnMsg(CSMSG *pMsg)
{
for(list<IMsgListener*>::iterator it = m_lstMsgListener.begin();
it != m_lstMsgListener.end(); it ++)
{
ASSERT( NULL != (*it) );
(*it) ->Notify(pMsg);
}
}
但是如果用户在Notify函数里不慎修改了m_lstListener,那么这段代码就会崩溃。
也就是说,观察者如果在Notify函数中调用Attach或者Detach函数,迭代子就会失效,系统就会崩溃!
在单线程环境下,我建议用“观察者队列缓存”的方式:
一、增加一个bool型的迭代标志,标志观察者队列是否处于迭代之中。即在OnMsg函数进入的时候,将其设为true,出去的时候设为false。
二、增加一个“观察者增删缓存”队列。
三、修改attach函数和detach函数。用户请求增删迭代子的时候,如果系统正在迭代过程中,那么先将增删请求保存在观察者增删缓存队列中,等待迭代完成之后再将这些
请求付诸实现。如果不处于迭代过程中,直接操作
观察者队列可以了。
12.命令(command)模式
命令(command)模式的结构很简单,但是对于消除代码间的耦合,清理代码去有着重要的影响。从最直观的角度来看,命令模式就是一个函数对象:一个作为对象的函数
。通过将函数封装为对象,就能够以参数的形式将其传递给其他函数或者对象,告诉它们在履行请求的过程中执行特定的操作。可以说,命令模式是携带行为信息的信使。
13Decorator装饰模式
作用:
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。
// 抽象基类,定义一个对象接口,可以为这个接口动态的添加职责.
class Component
{
public:
Component()
{
}
virtual ~Component()
{
}
// 纯虚函数,由派生类实现
virtual void Operation() = 0;
};
// 抽象基类,维护一个指向Component 对象的指针
class Decorator : public Component
{
public:
Decorator(Component* pComponent) : m_pComponent(pComponent)
{
}
virtual ~Decorator();
protected:
Component* m_pComponent;
};
// 派生自Component,在这里表示需要给它动态添加职责的类
class ConcreateComponent : public Component
{
public:
ConcreateComponent()
{
}
virtual ~ConcreateComponent()
{
}
virtual void Operation();
};
// 派生自Decorator,这里代表为ConcreateComponent动态添加职责的类
class ConcreateDecorator : public Decorator
{
public:
ConcreateDecorator(Component* pComponent) : Decorator(pComponent)
{
}
virtual ~ConcreateDecorator()
{
}
virtual void Operation();
private:
void AddedBehavior();
};
14 Adapt模式
作用:
将一个类的接口转换成客户希望的另外一个接口。Adapt 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
class Target
{
public:
Target(){}
virtual ~Target() {}
virtual void Request() = 0;
};
// 与被Adapt对象提供不兼容接口的类
class Adaptee
{
public:
Adaptee(){}
~Adaptee(){}
void SpecialRequest();
};
// 进行Adapt的类,采用聚合原有接口类的方式
class Adapter : public Target
{
public:
Adapter(Adaptee* pAdaptee);
virtual ~Adapter();
virtual void Request();
private:
Adaptee* m_pAdptee;
};
#endif
15 Brige模式
作用:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
class Implementor
{
public:
Implementor(){}
virtual ~Implementor(){}
virtual void OperationImpl() = 0;
};
// 继承自Implementor,是Implementor的不同实现之一
class ConcreateImplementorA: public Implementor
{
public:
ConcreateImplementorA(){}
virtual ~ConcreateImplementorA(){}
virtual void OperationImpl();
};
// 继承自Implementor,是Implementor的不同实现之一
class ConcreateImplementorB: public Implementor
{
public:
ConcreateImplementorB(){}
virtual ~ConcreateImplementorB(){}
virtual void OperationImpl();
};
// 维护一个Implementor类的指针
class Abstraction
{
public:
Abstraction(Implementor* pImplementor);
virtual ~Abstraction();
void Operation();
protected:
Implementor* m_pImplementor;
};
16 Composite模式
作用:
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对
单个对象和组合对象的使用具有一致性。
// 组合中的抽象基类
class Component
{
public:
Component()
{
}
virtual ~Component()
{
}
// 纯虚函数,只提供接口,没有默认的实现
virtual void Operation() = 0;
virtual void Add(Component* pChild)
{
}
virtual void Remove(Component* pChild)
{
}
virtual Component* GetChild(int nIndex)
{
return NULL;
}
};
// 派生自Component,是其中的叶子组件的基类
class Leaf : public Component
{
public:
Leaf()
{
}
virtual ~Leaf()
{
}
virtual void Operation()
{
std::cout << "Operation by leaf\n";
}
};
// 派生自Component,是其中的含有子件的组件的基类
class Composite : public Component
{
public:
Composite()
{
}
virtual ~Composite();
virtual void Operation();
virtual void Add(Component* pChild);
virtual void Remove(Component* pChild);
virtual Component* GetChild(int nIndex);
private:
// 采用list容器去保存子组件
std::list<Component*> m_ListOfComponent;
};
17 Flyweight模式
作用:
运用共享技术有效地支持大量细粒度的对象。
class Flyweight
{
public:
virtual ~Flyweight(){}
STATE GetIntrinsicState();
virtual void Operation(STATE& ExtrinsicState) = 0;
protected:
Flyweight(const STATE& state):m_State(state)
{
}
private:
STATE m_State;
};
class ConcreateFlyweight : public Flyweight
{
public:
ConcreateFlyweight(const STATE& state): Flyweight(state)
{
}
virtual ~ConcreateFlyweight()
{
}
virtual void Operation(STATE& ExtrinsicState);
};
class FlyweightFactory
{
public:
FlyweightFactory()
{
}
~FlyweightFactory();
Flyweight* GetFlyweight(const STATE& key)
{
std::list<Flyweight*>::iterator iter1, iter2;
for (iter1 = m_listFlyweight.begin(), iter2 = m_listFlyweight.end();iter1 != iter2;++iter1)
{
if ((*iter1)->GetIntrinsicState() == key)
{
std::cout << "The Flyweight:" << key << " already exits"<< std::endl;
return (*iter1);
}
}
std::cout << "Creating a new Flyweight:" << key << std::endl;
Flyweight* flyweight = new ConcreateFlyweight(key);
m_listFlyweight.push_back(flyweight);
}
private:
std::list<Flyweight*> m_listFlyweight;
};
18 Proxy模式
作用:
为其他对象提供一种代理以控制对这个对象的访问
// 定义了Proxy和RealSubject的公有接口,
// 这样就可以在任何需要使用到RealSubject的地方都使用Proxy. 我个人觉得Proxy并不必须是Subject类的子类
class Subject
{
public:
Subject()
{
}
virtual ~Subject()
{
}
virtual void Request() = 0;
};
// 真正使用的实体
class RealSubject : public Subject
{
public:
RealSubject();
virtual ~RealSubject()
{
}
virtual void Request();
};
#endif
// 代理类,含有一个指向RealSubject对象的指针
class Proxy : public Subject
{
public:
Proxy();
virtual ~Proxy();
virtual void Request(); //我觉得m_pRealSubject不一定非要在这里NEW,在main中NEW也可以
{
if(m_pRealSubject == NULL)
{
m_pRealSubject = new RealSubject;
}
m_pRealSubject-> Request();
}
private:
RealSubject* m_pRealSubject;
};
联系客服