学习《大话设计模式》,按照自己的体会写的c++代码,仅用于记录,有问题欢迎指出。
//FotoryMode.h
#pragma once
#include <string>
template<class T>
class Operation
{
public:
Operation(T numA,T numB):m_numA(numA),m_numB(numB)
{
}
Operation() = default;
virtual ~Operation() = default;
virtual T GetResult() = 0;
protected:
T m_numA = 0;
T m_numB = 0;
};
template<class T>
class AddOperation : public Operation<T>
{
public:
using Operation::Operation;
virtual T GetResult() override
{
return m_numA + m_numB;
}
};
template<class T>
class miusOperation : public Operation<T>
{
public:
using Operation::Operation;
virtual T GetResult() override
{
return m_numA - m_numB;
}
};
// 简单工厂模式
template<class T>
T GetResult(T numA, T numB, const std::string &opt)
{
Operation<T> *opet = nullptr;
if (opt == "+")
{
opet = new AddOperation<T>(numA,numB); // 使用的是父类的构造函数,故必须传参数进去
return opet->GetResult();
}
else if (opt == "-")
{
opet = new miusOperation<T>(numA, numB);
return opet->GetResult();
}
}
// 策略模式 就是简单将工厂模式的工厂函数放到一个类中,工厂函数是直接提供给客户使用,策略模式是提供Content类给客户使用
// 只要在分析过程中听到要在不同时间应用不同业务,就可以考虑用策略模式处理
template<class T>
class Content
{
public:
Content(T numA,T numB,const std::string &type)
{
if (type == "+")
{
m_opt = new AddOperation(numA,numB);
}
else if (type == "-")
{
m_opt = new miusOperation(numA, numB);
}
}
~Content()
{
if (m_opt != nullptr)
{
delete m_opt;
m_opt = nullptr;
}
}
T GetResult()
{
return m_opt->GetResult();
}
private:
Operation<T> *m_opt = nullptr;
};
// 工厂方法模式,是Operation类一个基类,Factory类一个基类,只要新增加一个运算符,就需要写一个继承Operation的运算子类,一个继承Factory的子类
template<class T>
class Factory
{
public:
Factory(T numA, T numB) :m_numA(numA), m_numB(numB)
{
}
virtual Operation<T>* CreatOperation() = 0;
protected:
T m_numA, m_numB;
};
template<class T>
class AddFactory:public Factory<T>
{
public:
using Factory::Factory;
Operation<T>* CreatOperation() override
{
return new AddOperation<T>(m_numA,m_numB);
}
};
void DoOperationWork()
{
AddFactory<int> *addFac = new AddFactory<int>(12, 13);
Operation<int> *opt = addFac->CreatOperation();
std::cout << opt->GetResult() << std::endl;
}
//DecorateMode.h
#pragma once
#include <iostream>
// 装饰模式
/*
使用构造函数来对对象进行包装,这样每个对象的实现,就跟这个对象的使用分离开了
每个对象只关心自己怎么实现,不需要关心如何被添加到对象链中。
这样就可以随意改变各个对象被添加的顺序,达到实现不同顺序的功能。 用户就可以有选择的按照不同顺序使用装饰功能封装对象
*/
/*
// 含Componet虚基类的装饰模式
class Componet
{
public:
virtual void Operation() = 0;
};
class Decorate : public Componet
{
public:
Decorate(Componet *cpt = nullptr):m_componet(cpt)
{
}
void Operation() override
{
if (m_componet != nullptr)
{
m_componet->Operation();
}
}
private:
Componet *m_componet = nullptr;
};*/
// 去除Componet基类版本的Decorate的装饰模式
class Decorate
{
public:
Decorate(Decorate *dcr = nullptr):m_decorate(dcr)
{
}
virtual ~Decorate()
{
}
virtual void Operation()
{
if (m_decorate != nullptr)
{
m_decorate->Operation();
}
}
private:
Decorate *m_decorate = nullptr;
};
class DecorateA : public Decorate
{
public:
using Decorate::Decorate;
std::string StringA()
{
return "DecorateA";
}
void Operation() override
{
Decorate::Operation(); // 是因为父类的Operation()函数会调用到传入参数对象的Operation()函数,故能起到一连串的叠加调用,因而不需要关心自身如何加入对象链中
std::cout << StringA().c_str()<<" 自己的数据" << std::endl;
}
};
class DecorateB : public Decorate
{
public:
using Decorate::Decorate;
void Operation() override
{
Decorate::Operation();
std::cout << StringB().c_str() << "自己的数据" << std::endl;
}
std::string StringB()
{
return "DecorateB";
}
};
class DecorateC : public Decorate
{
public:
using Decorate::Decorate;
void Operation() override
{
Decorate::Operation();
std::cout << "DecorateC 在自己的Operation()里输出自己的数据" << std::endl;
}
};
void DoWork()
{
/*DecorateA *a = new DecorateA;
DecorateB *b = new DecorateB(a);
DecorateC *c = new DecorateC(b);
c->Operation();
delete a;
a = nullptr;
delete b;
b = nullptr;
delete c;
c = nullptr;*/
DecorateB b;
DecorateA a(&b);
DecorateC c(&a);
DecorateA aa(&c);
/* 输出
DecorateB自己的数据
DecorateA 自己的数据
DecorateC 在自己的Operation()里输出自己的数据
DecorateA 自己的数据
*/
aa.Operation();
}
//ProxyMode.h
#pragma once
#include <iostream>
// 代理模式。 代理和实际主体都从Subject继承相同接口,代理保存了一份实际主体的对象。 当调用代理的接口时,实际调的是实际主体的接