ToB企服应用市场:ToB评测及商务社交产业平台
标题:
设计模式必知必会系列终章
[打印本页]
作者:
老婆出轨
时间:
2022-6-25 13:07
标题:
设计模式必知必会系列终章
目录
装饰器模式
工厂方法模式
抽象工厂模式
编辑
适配器模式
代理模式
装饰器模式
官方定义: 动态地给⼀个对象增加⼀些额外的职责。就增加功能而言,装饰器模式比生成子类更为灵活。 —— 《设计模式》GoF
通俗解释: 装饰器是为了给对象增加额外职责而产生的, 有点粉刷的意思, 房子已经存在了, 在房子的表面加上一层粉刷. (而且它的优势是相较于继承而言的, 相比直接继承, 装饰器更加灵活, 耦合度更低)
应对与 ”过度的采取类继承扩展对象的功能“ 的情况
继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致子类数量的膨胀。
(继承下来就是实实在在的一份负担, 代码的膨胀, 类的膨胀.) 但是很多时候其实我们没有必要去继承, 完全可以使用组合的方式来根据需求动态的实现对象功能的扩展, 以解决子类数量膨胀的问题. 使得功能扩展所带来的影响,代价最小,没必要说来一个新的功能扩展就新创建一个类。
这个类图其实很奇怪, 我刚看见的时候就在想,为啥又是继承, 又是组合的, 继承是为了复用之前的框架, 接口, 裸机 你只有有了之前的房子,才能粉刷装饰吧, 继承体现的是最初的裸机, 接口, 组合完成动态的修饰, 装饰。
这个组合还是组合抽象类本身,绝对看的让人很迷,组合的虽然是抽象类本身, 但是抽象类是一个接口,它可以代表它的一切派生类, 这样便使得这个组合对象可扩展性很强.
模式要点:
通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。
Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
记忆技巧: 继承复用接口,组合复用实现细节,动态组合
代码场景: 工资计算, 基本员工的工资是天数*100
, 经理员工是基本工资 + 加成add. 老板更是在经理员工的基础上增加10倍加成
实现代码如下:
#include <iostream>
using namespace std;
//此处我没有再写componet类了, 想写的兄弟可以添加喔
class Context {
public:
int day;//天数
int add;//加成
};
//分发奖金: 普通员工仅仅只是day * 100
//经理 还有加成
//老总等等加成更加牛逼, 在经理的基础上再10倍加成
//基础员工工资
//DecoratorClass装饰器基类
class BaseWocker {
public:
BaseWocker(BaseWocker* _base) : base(_base) {
}
virtual int CalculateSlary(Context& ctx) {
//计算基本工资
return ctx.day * 100;
}
virtual ~BaseWocker() {}
protected:
BaseWocker* base;
};
//继承复用接口
//BaseWocker继承下来的是裸机, 最初框架, 接口
//组合扩展细节. 运算.
class Manager : BaseWocker {
public:
Manager(BaseWocker* _base = nullptr) : BaseWocker(_base) {
}
virtual int CalculateSalary(Context& ctx) {
int basesalary = base->CalculateSlary(ctx);
//...在组合对象的基础上进行扩展运算
return basesalary + ctx.add;
}
};
//Decorator
class Boss : public BaseWocker {
public:
Boss(BaseWocker* _base) : BaseWocker(_base) {
}
virtual int CalculateSalary(Context& ctx) {
int basesalary = base->CalculateSlary(ctx);
//...在组合对象的基础上进行扩展运算
return (basesalary + (ctx.add * 10));
}
};
复制代码
如下是大佬写的一份代码: 大家也可以赏析一下:
//业务操作, Component抽象基类
class Stream{
public:
virtual char Read(int number)=0;
virtual void Seek(int position)=0;
virtual void Write(char data)=0;
virtual ~Stream(){}
};
//主体类具体的Component类
class FileStream: public Stream{
public:
virtual char Read(int number){
//读文件流
}
virtual void Seek(int position){
//定位文件流
}
virtual void Write(char data){
//写文件流
}
};
class NetworkStream :public Stream{
public:
virtual char Read(int number){
//读网络流
}
virtual void Seek(int position){
//定位网络流
}
virtual void Write(char data){
//写网络流
}
};
class MemoryStream :public Stream{
public:
virtual char Read(int number){
//读内存流
}
virtual void Seek(int position){
//定位内存流
}
virtual void Write(char data){
//写内存流
}
};
//扩展操作
//扩展操作采取的是装饰器类, has a 的特征
DecoratorStream: public Stream{
protected:
Stream* stream;//...
DecoratorStream(Stream * stm):stream(stm){
}
};
//具体的decorator类
class CryptoStream: public DecoratorStream {
public:
CryptoStream(Stream* stm):DecoratorStream(stm){
}
virtual char Read(int number){
//额外的加密操作...
stream->Read(number);//读文件流
}
virtual void Seek(int position){
//额外的加密操作...
stream::Seek(position);//定位文件流
//额外的加密操作...
}
virtual void Write(byte data){
//额外的加密操作...
stream::Write(data);//写文件流
//额外的加密操作...
}
};
class BufferedStream : public DecoratorStream{
Stream* stream;//...
public:
BufferedStream(Stream* stm):DecoratorStream(stm){
}
//...
};
复制代码
工厂方法模式
官方定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。——《设计模式》GoF
通俗解释:简单来说就是在工厂基类中定义一个抽象接口, 将整个接口的实例化延迟到一个具体的子类工厂(具体工厂),解耦合. ---- 之后对于工厂的依赖都是依赖稳定的工厂基类
这个类图感觉不算特别完善, 最好可以在Factory下面在继承具体的Factory感觉比较好.
实现代码如下:
[code]//抽象产品类class Operator {public: Operator(int l, int r) : lhs(l) , rhs(r) { } //抽象操作 virtual int Operation() = 0; virtual ~Operator() {}protected: int lhs; int rhs;};//具体产品类class AddOperator : public Operator{public: AddOperator(int l, int r) : Operator(l, r) { } virtual int Operation() { return lhs + rhs; }};class SubOperator : public Operator{public: SubOperator(int l, int r) : Operator(l, r) { } virtual int Operation() { return lhs - rhs; }};class MulOperator : public Operator{public: MulOperator(int l, int r) : Operator(l, r) { } virtual int Operation() { return lhs * rhs; }};class DivOperator : public Operator{public: DivOperator(int l, int r) : Operator(l, r) { } virtual int Operation() { if (rhs == 0) { cerr r; cout op; OperatorFactory* factory = nullptr; //创建工厂 switch (op) { case '+': { factory = new AddOperatorFactory(); } break; case '-': { factory = new SubOperatorFactory(); } break; case '*': { factory = new MulOperatorFactory(); } break; case '/': { factory = new DivOperatorFactory(); } break; } //生产产品运行Operaction cout CreateMethod(l, r)->Operation()
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4