c++ - 特定子类的装饰器

标签 c++ design-patterns

我有以下类(class):

class Stream {};

class FileStream : public Stream {};

class NetworkStream : public Stream {};

每个类都有一个write()方法(虚拟的)。

我可以在两种类型的媒体上使用 FileStream:HDD 和 SSD。如果我正在写入 HDD,我不会对 FileStream 已经提供的内容做任何特别的事情。但是,如果我正在编写 SSD,则在调用 write() 之前我需要执行一些逻辑。在 FileStream 中,我不知道我要写入的媒体是什么。只有调用站点知道。我想在这里使用 decorator,但 decorator 旨在与所有流一起使用。我只想在某些情况下扩展 NetworkStream 的功能。某种形式的装饰器在这里合适吗?如果不是,我应该使用什么设计模式?如果我们假设 FileStream::write() 只是将整个内部缓冲区刷新到文件并将其保存到磁盘,那么装饰器将需要在写入流之前将一些元数据写入流。

我想创建一个不使用继承的简单装饰器类:

class FileStreamDecorator
{
public:
  FileStreamDecorator( FileStream& stream ) : m_stream( stream )  {}

  void write() {
    m_stream << "Some Metadata";
    m_stream.write();
  }

private:
  FileStream& m_stream;
};

它会像这样使用:

FileStream stream;
stream << "Complete file data";

// At this point we know we are writing to SSD, so we must use the decorator
FileStreamDecorator decorator( stream );
decorator.write();

这是一个合适的解决方案吗?谁能想到更好的方法?

最佳答案

Would this be an appropriate solution? Can anyone think of a better way?

没有。您正在创建一个装饰器类,并依赖客户端代码在需要时不要忘记使用它。

如果客户端代码忘记执行额外的步骤,代码看起来没问题(客户端代码中没有任何建议应该在那里初始化装饰器)。

在一个月(或就此而言五年)内,您将忘记这一点,或者转移到其他项目,维护该项目的人将不得不意识到需要在客户端中初始化一个新对象。

最好使用 SSDFileStream 特化,它会覆盖基类的 write()(默认行为),在内部调用基类版本,然后执行任何额外的步骤。

我能想到的最佳实现:

class FileStream {
    virtual void write();
};

class SSDFileStream: public FileStream {
    virtual void write() {
        FileStream::write();
        write_ssd();
    }
protected:
    void write_ssd();
};

此外,您可以将 FileStream 抽象化,并添加 HDDFileStream 特化。如果 HDDFileStream 检测到它正在 SSD 上写入,它可能会抛出异常。如果您要求它在 HDD 路径上写入,SSDFileStream 可能会做同样的事情。

这将使客户端代码易于正确编写,并且不可能“*”编写错误。


'* 编写错误/不稳定/脆弱/丑陋的代码从来都不是不可能的,但您仍然可以让它难以实现。

关于c++ - 特定子类的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16195493/

相关文章:

java - 我可以并且是否需要避免单例模式?

javascript - 使用事件在 View 设计模式之间进行通信

java - 改变一下单例模式

c++ - 以编程方式为 ListView 项目构建 UI

java - 多国数据库表和java对象

java - 定义行动和目标的设计模式

c++ - 重载运算符 []

c++ - 让 CMake 在可能的情况下选择静态链接?

c++ - 应答一个 UDP 数据包

c++ - 排序时更改排序顺序是未定义的行为吗?