91大神网站建设,江苏省省建设集团网站,合肥网站建设电话,电脑网页游戏排行榜前十名前言
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法#xff0c;观察者模式#xff0c;策略模式)
工程方法
定义
定义一个用于创建对象的接口#xff0c;让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。 ——《设…前言
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法观察者模式策略模式)
工程方法
定义
定义一个用于创建对象的接口让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。 ——《设计模式》GoF
要点
解决创建过程比较复杂希望对外隐藏这些细节的场景
比如连接池、线程池隐藏对象真实类型对象创建会有很多参数来决定如何创建创建对象有复杂的依赖关系
本质
延迟到子类来选择实现
结构图 举例
实现一个导出数据的接口让客户选择数据的导出方式
代码
class IExport
{
protected:IExport() {}virtual ~IExport() {}
public:virtual void exportFile() 0;
};class JSONExport :public IExport
{
public:JSONExport() {}~JSONExport() {}void exportFile(){std::cout export json file std::endl;}
};
class TxtFileExport :public IExport
{
public:TxtFileExport() {}~TxtFileExport() {}void exportFile(){std::cout export txt file std::endl;}
};
class XMLExport :public IExport
{
public:XMLExport() {}~XMLExport() {}void exportFile(){std::cout export xml file std::endl;}
};class IFactoryMethodExport
{
public:virtual IExport* createExport() 0;//创建比较复杂使用一个函数来创建
};class FactoryMethodJSONExport :public IFactoryMethodExport
{
public:IExport* createExport() {//比较多的参数初始化jsonExport new JSONExport();//这里没有使用参数这些//其他初始化操作}
private:JSONExport* jsonExport;
};class FactoryMethodXMLExport :public IFactoryMethodExport
{
public:IExport* createExport() {//比较多的参数初始化xmlExport new XMLExport();//这里没有使用参数这些//其他初始化操作}
private:XMLExport* xmlExport;
};class FactoryMethodTxtFileExport :public IFactoryMethodExport
{
public:IExport* createExport() {//比较多的参数初始化txtFileExport new TxtFileExport();//这里没有使用参数这些//其他初始化操作return txtFileExport;}
private:TxtFileExport* txtFileExport;
};抽象工厂
定义
提供一个接口让该接口负责创建一系列“相关或者相互依赖的对象”无需指定它们具体的类。——《设计模式》GoF 其实和工厂方法是类似的只是在工厂中创建多个对象。
结构图 例子
实现一个拥有导出导入数据的接口让客户选择数据的导出导入方式
代码
class IExport {
public:virtual bool Export(const std::string data) 0;virtual ~IExport(){}
};class ExportXml : public IExport {
public:virtual bool Export(const std::string data) {return true;}
};class ExportJson : public IExport {
public:virtual bool Export(const std::string data) {return true;}
};class ExportTxt : public IExport {
public:virtual bool Export(const std::string data) {return true;}
};class ExportCSV : public IExport {
public:virtual bool Export(const std::string data) {return true;}
};class IImport {
public:virtual bool Import(const std::string data) 0;virtual ~IImport(){}
};class ImportXml : public IImport {
public:virtual bool Import(const std::string data) {return true;}
};class ImportJson : public IImport {
public:virtual bool Import(const std::string data) {return true;}
};class ImportTxt : public IImport {
public:virtual bool Import(const std::string data) {return true;}
};// 对于初学者 知道扩展代码
// 5年
class ImportCSV : public IImport {
public:virtual bool Import(const std::string data) {// ....return true;}
};class IDataApiFactory {
public:IDataApiFactory() {_export nullptr;_import nullptr;}virtual ~IDataApiFactory() {if (_export) {delete _export;_export nullptr;}if (_import) {delete _import;_import nullptr;}}bool Export(const std::string data) {if (_export nullptr) {_export NewExport();}return _export-Export(data);}bool Import(const std::string data) {if (_import nullptr) {_import NewImport();}return _import-Import(data);}
protected:virtual IExport * NewExport(/* ... */) 0;virtual IImport * NewImport(/* ... */) 0;
private:IExport *_export;IImport *_import;
};class XmlApiFactory : public IDataApiFactory {
protected:virtual IExport * NewExport(/* ... */) {// 可能有其它操作或者许多参数IExport * temp new ExportXml;// 可能之后有什么操作return temp;}virtual IImport * NewImport(/* ... */) {// 可能有其它操作或者许多参数IImport * temp new ImportXml;// 可能之后有什么操作return temp;}
};class JsonApiFactory : public IDataApiFactory {
protected:virtual IExport * NewExport(/* ... */) {// 可能有其它操作或者许多参数IExport * temp new ExportJson;// 可能之后有什么操作return temp;}virtual IImport * NewImport(/* ... */) {// 可能有其它操作或者许多参数IImport * temp new ImportJson;// 可能之后有什么操作return temp;}
};
class TxtApiFactory : public IDataApiFactory {
protected:virtual IExport * NewExport(/* ... */) {// 可能有其它操作或者许多参数IExport * temp new ExportTxt;// 可能之后有什么操作return temp;}virtual IImport * NewImport(/* ... */) {// 可能有其它操作或者许多参数IImport * temp new ImportTxt;// 可能之后有什么操作return temp;}
};class CSVApiFactory : public IDataApiFactory {
protected:virtual IExport * NewExport(/* ... */) {// 可能有其它操作或者许多参数IExport * temp new ExportCSV;// 可能之后有什么操作return temp;}virtual IImport * NewImport(/* ... */) {// 可能有其它操作或者许多参数IImport * temp new ImportCSV;// 可能之后有什么操作return temp;}
};// 相关性 依赖性 工作当中
int main () {IDataApiFactory *factory new CSVApiFactory();factory-Import(hello world);factory-Export(hello world);return 0;
}责任链模式
定义
使多个对象都有机会处理请求从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链并沿着这条链传递请求直到有一个对象处理它为止。 ——《设计模式》GoF
要点
解耦请求方和处理方请求方不知道请求是如何被处理处理方的组成是由相互独- 立的子处理构成子处理流程通过链表的方式连接子处理请求可以按任意顺序组合责任链请求强调请求最终由一个子处理流程处理通过了各个子处理条件判断责任链扩展就是功能链功能链强调的是一个请求依次经由功能链中的子处理流程处理将职责以及职责顺序运行进行抽象那么职责变化可以任意扩展同时职责顺序也可以任意扩展
本质
分离职责动态组合
结构图 例子
请求流程1 天内需要主程序批准3 天内需要项目经理批准3 天以上需要老板批准 在前面链接的说明了设计模式主要是设计需求的变化点稳定点是固定的流程。 在这里稳定点是处理流程是稳定的(首选判断是否能够处理如果不能处理则交给更高层处理可以抽象出是否能够处理接口和处理接口)。变化点包括天数职责人个数(后续可能会增加更多的项目职责)。
代码
#include string
struct WorkerContext {std::string name;int day;
};class IWorker{
public:IWorker(WorkerContext context) :context(context) { }//处理流程是固定的稳定点不变bool handle() {if (isCanHandle()) {//可以处理return handRequest();}else if(next){//不可以处理,交给下个处理者处理return next-handle();}std::cout 无法处理 std::endl;return false;}void setNextHandler(IWorker* _next)//设置下一个处理者{next _next;}
protected:virtual bool isCanHandle() 0;//是否可以处理virtual bool handRequest() 0;//处理WorkerContext context;
private:IWorker* next nullptr;//下一个流程处理者
};//
class MainProgram :public IWorker {
public:MainProgram(WorkerContext context) :IWorker(context) {}
private:bool isCanHandle() {if (context.day 1){return true;}return false;}bool handRequest() {std::cout MainProgram 同意 context.name 天数 context.day std::endl;return true;}
};
class ProjectManager :public IWorker {
public:ProjectManager(WorkerContext context) :IWorker(context) {}
private:bool isCanHandle() {if (context.day 3){return true;}return false;}bool handRequest() {std::cout ProjectManager 同意 context.name 天数 context.day std::endl;return true;}
};class Boss :public IWorker {
public:Boss(WorkerContext context) :IWorker(context) {}
private:bool isCanHandle() {if (context.day 3 context.day 10){return true;}return false;}bool handRequest() {std::cout Boss 同意 context.name 天数 context.day std::endl;return true;}
};int main{WorkerContext context;context.day 10;context.name susan;IWorker* worker1 new MainProgram(context);IWorker* worker2 new ProjectManager(context);IWorker* worker3 new Boss(context);worker1-setNextHandler(worker2);worker2-setNextHandler(worker3);worker1-handle();
}装饰器模式
定义
动态地给一个对象增加一些额外的职责。就增加功能而言装饰器模式比生产子类更为灵活。—— 《设计模式》GoF
要点
- 通过采用组合而非继承的手法 装饰器模式实现了在运行时动态扩展对象功能的能力而且可以根据需要扩展多个功能。 避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
- 不是解决“多子类衍生问题”问题而是解决“父类在多个方向上的扩展功能”问题
- 装饰器模式把一系列复杂的功能分散到每个装饰器当中一般一个装饰器只实现一个功能实现复用装饰器的功能本质
动态组合
例子
普通员工有销售奖金累计奖金部门经理除此之外还有团队奖金后面可能会添加环比增长奖金同时可能针对不同的职位产生不同的奖金组合
代码
#include iostream
// 普通员工有销售奖金累计奖金部门经理除此之外还有团队奖金后面可能会添加环比增长奖金同时可能产生不同的奖金组合
// 销售奖金 当月销售额 * 4%
// 累计奖金 总的回款额 * 0.2%
// 部门奖金 团队销售额 * 1%
// 环比奖金 (当月销售额-上月销售额) * 1%
// 销售后面的参数可能会调整
using namespace std;
class Context {
public:bool isMgr;// User user;// double groupsale;
};class CalcBonus {
public:CalcBonus(CalcBonus * c nullptr) : cc(c) {}virtual double Calc(Context ctx) {return 0.0; // 基本工资}virtual ~CalcBonus() {}protected:CalcBonus* cc;
};class CalcMonthBonus : public CalcBonus {
public:CalcMonthBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context ctx) {double mbonus /* 计算流程忽略*/; return mbonus cc-Calc(ctx);}
};class CalcSumBonus : public CalcBonus {
public:CalcSumBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context ctx) {double sbonus /* 计算流程忽略*/; return sbonus cc-Calc(ctx);}
};class CalcGroupBonus : public CalcBonus {
public:CalcGroupBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context ctx) {double gbnonus /* 计算流程忽略*/; return gbnonus cc-Calc(ctx);}
};class CalcCycleBonus : public CalcBonus {
public:CalcCycleBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context ctx) {double gbnonus /* 计算流程忽略*/; return gbnonus cc-Calc(ctx);}
};int main() {// 1. 普通员工Context ctx1;CalcBonus *base new CalcBonus();CalcBonus *cb2 new CalcSumBonus(base);CalcBonus *cb1 new CalcMonthBonus(cb2);cb2-Calc(ctx1);// 2. 部门经理Context ctx2;CalcBonus *cb3 new CalcGroupBonus(cb2);cb3-Calc(ctx2);
}