一、3个具体类继承一个抽象类,单一责任原则各自实现抽象基类中的三个方法。
#pragma once
#include<iostream>
//业务操作
class Stream
{
public:
virtual void Read(int number)const = 0;
virtual void Seek(int position)const = 0;
virtual void Write(char data) = 0;
virtual ~Stream() {}
};
//主体类
class FileStream : public Stream
{
public:
virtual void Read(int number)const override
{
//读文件流
std::cout << "读文件流" << std::endl;
}
virtual void Seek(int position)const override
{
//定位文件流
}
virtual void Write(char data)override
{
//写文件流
}
};
class NetworkStream :public Stream
{
public:
virtual void Read(int number)const override
{
//读网络流
std::cout << "读网络流" << std::endl;
}
virtual void Seek(int position)const override
{
//定位网络流
}
virtual void Write(char data)override
{
//写网络流
}
};
class MemoryStream :public Stream
{
public:
virtual void Read(int number)const override
{
//读内存流
std::cout << "读内存流" << std::endl;
}
virtual void Seek(int position)const override
{
//定位内存流
}
virtual void Write(char data) override
{
//写内存流
}
};
二、1、“一“”中是常见的写法,但是如果业务类满足不了需求时,就需要增加类的功能,但是我们又不希望对原有类进行修改,此时常用decorator(装饰模式)。
2、把Stream* stream从CryptoStream、BufferedStream装饰类提出来封装成装饰类的中间类,也可以把Stream放在各个装饰类中,提取出来封装成中间类是比较标准的写法。但有不应该提取到Stream类中,因为FileStream、NetworkStream 、MemoryStream类并未用到此方法。
3、CryptoStream、BufferedStream类从类的关系上展现为is a Stream和has a Stream同时存在的,但对用户表现为is a Stream的关系,一般看到这种类绝大部分就是decorator。
4、CryptoStream、BufferedStream类的方法中通过Stream 调用FileStream、NetworkStream 、MemoryStream等类的方法以外的操作,即为装饰内容,或者说需求增加内容。
#pragma once
#include "Stream.h"
//扩展操作中间类
class DecoratorStream :
public Stream
{
private:
Stream* stream;
protected:
DecoratorStream(Stream * stm) :stream(stm)
{
}
Stream* getStream()const
{
return stream;
}
};
//文件流扩展操作,额外的加密操作,即为装饰内容
class CryptoStream : public DecoratorStream
{
public:
CryptoStream(Stream* stm) :DecoratorStream(stm)
{
}
virtual void Read(int number)const override
{
std::cout << "读文件流扩展操作" << std::endl;
//额外的加密操作...
getStream()->Read(number);//读文件流
}
virtual void Seek(int position)const override
{
//额外的加密操作...
getStream()->Seek(position);//定位文件流
//额外的加密操作...
}
virtual void Write(char data)override
{
//额外的加密操作...
getStream()->Write(data);//写文件流
//额外的加密操作...
}
};
//内存流扩展操作,额外的加密操作,即为装饰内容
class BufferedStream : public DecoratorStream
{
public:
BufferedStream(Stream* stm) :DecoratorStream(stm)
{
}
virtual void Read(int number)const override
{
std::cout << "读内存流扩展操作" << std::endl;
//额外的加密操作...
getStream()->Read(number);//读内存流
}
virtual void Seek(int position)const override
{
//额外的加密操作...
getStream()->Seek(position);//定位内存流
//额外的加密操作...
}
virtual void Write(char data)override
{
//额外的加密操作...
getStream()->Write(data);//写内存流
//额外的加密操作...
}
};
四、1创建建装饰类正确,2和3创建装饰类编译和运行都能通过,但却是错误的,装饰类应该用自己对应的业务类创建。原因是getStream()->Read(number);总是动态联编到用于创建自己类的对应的方法,业务上而本应该动态联编到对应的业务类方法。
#include "Stream.h"
#include "DecoratorStream.h"
int main()
{
//1
Stream* s1 = new FileStream(); //普通文件流类对象
Stream* s2 = new CryptoStream(s1); //文件流装饰类对象
s2->Read(1);
std::cout << std::endl;
//2
Stream* s3 = new BufferedStream(s1); //内存流装饰类对象,初始化为文件流类对象
s3->Read(1);
std::cout << std::endl;
//3
Stream* s4 = new BufferedStream(s2); //内存流装饰类对象,初始化为文件流类对象
s4->Read(1);
//注意:2和3创建装饰类错误,装饰类应该用自己对应的业务类创建
//原因:getStream()->Read(number);动态联编到用于创建装饰的对应的方法,而本应该动态联编到对应的业务类方法
/*输出
读文件流扩展操作
读文件流
读内存流扩展操作
读文件流
读内存流扩展操作
读文件流扩展操作
读文件流
*/
}
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810