设计模式分为三种类型
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
设计原则
面向对象有几个原则:开闭原则(Open Closed Principle,OCP)
里氏代换原则(Liskov Substitution Principle,LSP)
依赖倒转原则(Dependency Inversion Principle,DIP)
接口隔离原则(Interface Segregation Principle,ISP)
合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)
开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。其他几条,则可以看做是开闭原则的实现方法。设计模式就是实现了这些原则,从而达到了代码复用、增加可维护性的目的。
简单工厂模式
主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。
GOOD:适用于不同情况创建不同的类时
BUG:客户端必须要知道基类和工厂类,耦合性差
(工厂类与基类为关联关系)
例:
//基类
class COperation
{
public:
int m_nFirst;
int m_nSecond;
virtual double GetResult()
{
double dResult=0;
return dResult;
}
};
//加法
classAddOperation : public COperation
{
public:
virtual double GetResult()
{
return m_nFirst+m_nSecond;
}
};
//减法
classSubOperation : public COperation
{
public:
virtual double GetResult()
{
return m_nFirst-m_nSecond;
}
};
//工厂类
class CCalculatorFactory
{
public:
staticCOperation* Create(char cOperator);
};
COperation* CCalculatorFactory::Create(char cOperator)
{
COperation *oper;
//在C#中可以用反射来取消判断时用的switch,在C++中用什么呢?RTTI??
switch (cOperator)
{
case '+':
oper=newAddOperation();
break;
case '-':
oper=newSubOperation();
break;
default:
oper=newAddOperation();
break;
}
return oper;
}
客户端
int main()
{
int a,b;
cin>>a>>b;
COperation *op=CCalculatorFactory::Create('-');
op->m_nFirst=a;
op->m_nSecond=b;
cout<<op->GetResult()<<endl;
return 0;
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------策略模式
定义算法家族,分别封装起来,让它们之间可以互相替换,让算法变化,不会影响到用户
GOOD:适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
BUG:客户端要做出判断
//策略基类
class COperation
{
public:
int m_nFirst;
int m_nSecond;
virtual double GetResult()
{
double dResult=0;
return dResult;
}
};
//策略具体类—加法类
classAddOperation : public COperation
{
public:
AddOperation(int a,int b)
{
m_nFirst=a;
m_nSecond=b;
}
virtual double GetResult()
{
return m_nFirst+m_nSecond;
}
};
class Context
{
private:
COperation* op;
public:
Context(COperation*temp)
{
op=temp;
}
doubleGetResult()
{
returnop->GetResult();
}
};
//客户端
int main()
{
int a,b;
char c;
cin>>a>>b;
cout<<”请输入运算符:;
cin>>c;
switch(c)
{
case ‘+’:
Context *context=newContext(new AddOperation(a,b));
cout<<context->GetResult()<<endl;
break;
default:
break;
}
return 0;
}
策略与工厂结合
GOOD:客户端只需访问Context类,而不用知道其它任何类信息,实现了低耦合。
在上例基础上,修改下面内容
class Context
{
private:
COperation* op;
public:
Context(charcType)
{
switch (cType)
{
case '+':
op=newAddOperation(3,8);
break;
default:
op=newAddOperation();
break;
}
}
double GetResult()
{
return op->GetResult();
}
};
//客户端
int main()
{
int a,b;
cin>>a>>b;
Context *test=newContext('+');
cout<<test->GetResult()<<endl;
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
装饰模式
动态地给一个对象添加一些额外的职责(不重要的功能,只是偶然一次要执行),就增加功能来说,装饰模式比生成子类更为灵活。建造过程不稳定,按正确的顺序串联起来进行控制。
GOOD:当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。
#include<string>
#include<iostream>
using namespacestd;
//人
class Person
{
private:
string m_strName;
public:
Person(string strName)
{
m_strName=strName;
}
Person(){}
virtual void Show()
{
cout<<"装扮的是:"<<m_strName<<endl;
}
};
//装饰类
class Finery :public Person
{
protected:
Person*m_component;
public:
voidDecorate(Person* component)
{
m_component=component;
}
virtual voidShow()
{
m_component->Show();
}
};
//T恤
class TShirts:public Finery
{
public:
virtual void Show()
{
cout<<"TShirts"<<endl;
m_component->Show();
}
};
//裤子
class BigTrouser:public Finery
{
public:
virtual void Show()
{
cout<<" BigTrouser"<<endl;
m_component->Show();
}
};
//客户端
int main()
{
Person *p=new Person("小李");
BigTrouser *bt=new BigTrouser();
TShirts *ts=new TShirts();
bt->Decorate(p);
ts->Decorate(bt);
ts->Show();
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------代理模式
GOOD:远程代理,可以隐藏一个对象在不同地址空间的事实
虚拟代理:通过代理来存放需要很长时间实例化的对象
安全代理:用来控制真实对象的访问权限
智能引用:当调用真实对象时,代理处理另外一些事
#include<string>
#include<iostream>
using namespacestd;
//定义接口
class Interface
{
public:
virtual void Request()=0;
};
//真实类
class RealClass: public Interface
{
public:
virtual void Request()
{
cout<<"真实的请求"<<endl;
}
};
//代理类
class ProxyClass: public Interface
{
private:
RealClass* m_realClass;
public:
virtual void Request()
{
m_realClass= new RealClass();
m_realClass->Request();
delete m_realClass;
}
};
客户端:
int main()
{
ProxyClass* test=new ProxyClass();
test->Request();
return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------工厂方法模式
GOOD:修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
#include<string>
#include<iostream>
using namespacestd;
//实例基类,相当于Product(为了方便,没用抽象)
class LeiFeng
{
public:
virtual void Sweep()
{
cout<<"雷锋扫地"<<endl;
}
};
//学雷锋的大学生,相当于ConcreteProduct
class Student:public LeiFeng
{
public:
virtual void Sweep()
{
cout<<"大学生扫地"<<endl;
}
};
//学雷锋的志愿者,相当于ConcreteProduct
class Volenter:public LeiFeng
{
public :
virtual void Sweep()
{
cout<<"志愿者"<<endl;
}
};
//工场基类Creator
class LeiFengFactory
{
public:
virtual LeiFeng*CreateLeiFeng()
{
return newLeiFeng();
}
};
//工场具体类
class StudentFactory : public LeiFengFactory
{
public :
virtual LeiFeng*CreateLeiFeng()
{
return newStudent();
}
};
class VolenterFactory : public LeiFengFactory
{
public:
virtual LeiFeng*CreateLeiFeng()
{
return newVolenter();
}
};
//客户端
int main()
{
LeiFengFactory *sf=new StudentFactory ();
LeiFeng *s=sf->CreateLeiFeng();
s->Sweep();
delete s;
delete sf;
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------原型模式
GOOD:从一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。并能提高创建的性能。说白了就COPY技术,把一个对象完整的COPY出一份。
#include<iostream>
#include<vector>
#include<string>
using namespacestd;
class Prototype//抽象基类
{
private:
string m_strName;
public:
Prototype(string strName){ m_strName =strName; }
Prototype() { m_strName = " ";}
void Show()
{
cout<<m_strName<<endl;
}
virtualPrototype* Clone() = 0 ;
} ;
// classConcretePrototype1
classConcretePrototype1 : public Prototype
{
public:
ConcretePrototype1(string strName) :Prototype(strName){}
ConcretePrototype1(){}
virtualPrototype* Clone()
{
ConcretePrototype1*p = new ConcretePrototype1() ;
*p = *this; //复制对象
return p ;
}
} ;
// classConcretePrototype2
classConcretePrototype2 : public Prototype
{
public:
ConcretePrototype2(string strName) :Prototype(strName){}
ConcretePrototype2(){}
virtual Prototype* Clone()
{
ConcretePrototype2 *p = newConcretePrototype2() ;
*p = *this ; //复制对象
return p ;
}
} ;
//客户端
int main()
{
ConcretePrototype1* test = newConcretePrototype1("小王");
ConcretePrototype2*test2 = (ConcretePrototype2*)test->Clone();
test->Show();
test2->Show();
return 0;
}