看起来像是一个很好的策略来组合像这样的对象(作为策略):
template<typename FluxType, typename SourceType>
class Model : public FluxType, public SourceType
{ };
//later in the code:
template<typename FluxType, typename SourceType>
class ConcreteModel : public Model<FluxType, SourceType>
{};
但是,FluxType
和SourceType
是使用相同数据的类。所以我使用了虚拟继承:
class ConcreteModelProps{};
class ConcreteFlux : virtual public ConcreteModelProps
{};
class ConcreteFlux2 : virtual public ConcreteModelProps
{/*sligthly different implementation*/};
class ConcreteSource : virtual public ConcreteModelProps
{};
class DefaultSource2
{/*no need for data*/};
这样我可以使用不同的ConcreteModel
和FluxType
对象撰写SourceType
。
ConcreteModel<ConcreteFlux, DefaultSource2> /*or whatever*/.
事实是ConcreteModelProps
中定义的数据与ConcreteModel
密切相关。在我看来,我至少做错了什么。如何让这个设计变得更好?最好没有虚拟继承?
thx,dodol
答案 0 :(得分:1)
嗯,这很简单:你ConcreteFlux
继承了ConcreteModelProps
,违反了LISKOV Substitution Principle;所以你付出代价才是正确的。
现在,如果您外化数据,您可能正在使用更健全的模型。
template <typename FluxType, typename SourceType>
class Model {
public:
typedef typename FluxType::DataType DataType;
}; // class Model
template <typename M>
class ConcreteModel: public M {
}; // class ConcreteModel
然后:
class ConcreteFlux {
public:
typedef ConcreteModelProps DataType;
};
class ConcreteSource {
public:
typedef ConcreteModelProps DataType;
};
template <typename Data>
class DefaultSource {
typedef Data DataType;
};
最后:
class ConcreteModel<Model<ConcreteFlux, ConcreteSource>> {};
当然,这意味着现在需要将ConcreteFlux
和ConcreteSource
的所有方法都传递给每个方法中的句柄ConcreteModelProps
。这就是外化的意义所在。