我有一个类从文件中读取一些数据然后解码该数据。
我正在尽可能地将该类作为通用类,即我希望它能够解码任何类型的数据。
解码器本身就是一个通用接口。
我看到两个选项:
注入 - 在结构函数中获取正确的解码器作为参数
MyReader(解码器< T>解码器){ _decoder = decoder}
继承 - 提供将返回正确解码器的虚拟方法
MyReader(); 虚拟解码器< T> GetDecoder()= 0;
我的类的用户只需要继承该类并仅实现“GetDecoder”。
注射解决方案可帮助您减少使用的类数量,同时让用户了解特定的编码器。
继承将需要许多类,但封装了编码器的用法。
什么被认为是更好的方法?
答案 0 :(得分:0)
我认为你的“注入”方法是通过一个共同的基类存储解码器,而你考虑的替代方案更像是:
MyReader(AbstractDecoder& decoder) : _decoder(decoder) { };
MyReader() { private: virtual Decoder<T>& GetDecoder() = 0; };
有几点需要考虑:
注入意味着客户端代码必须在创建和指定Decoder
以及处理其生命周期中可能发生的错误方面发挥更积极的作用,而对于继承,它隐含在派生的选择中MyReader
错误可以使类和错误处理更加统一;
Decoder
是否被构造函数复制(如你所做)方面需要更多的客户端意识,或者调用者需要确保比读者更长的生命周期,是否可以将相同的解码器传递给多个MyReader
构造函数等。 - 更容易混淆和容易出错注入意味着MyReader
API可能允许在阅读器的生命周期内指定另一个解码器
继承,你最终会有更多的类,客户端代码需要小心谨慎以避免切片,而注入它的MyReader
本身需要一点点小心存储/复制时,但至少是集中的,因此更容易获得并保持正确
CRTP是另一种选择,具有编译时解析和优化(死代码消除,内联等)。