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