我知道拥有钻石继承被认为是不好的做法。然而,我有两个案例,我觉得钻石继承非常适合。我想问,在这些情况下你会建议我使用钻石继承,还是有其他设计可以更好。
Case 1:我想创建代表系统中不同类型“操作”的类。这些动作按几个参数分类:
- 该操作可以是“读”或“写”。
- 该操作可以有延迟或没有延迟(它不仅仅是 1 个参数。它会显着改变行为)。
- 操作的“流类型”可以是 FlowA 或 FlowB。
我打算有以下设计:
// abstract classes
class Action
{
// methods relevant for all actions
};
class ActionRead : public virtual Action
{
// methods related to reading
};
class ActionWrite : public virtual Action
{
// methods related to writing
};
class ActionWithDelay : public virtual Action
{
// methods related to delay definition and handling
};
class ActionNoDelay : public virtual Action {/*...*/};
class ActionFlowA : public virtual Action {/*...*/};
class ActionFlowB : public virtual Action {/*...*/};
// concrete classes
class ActionFlowAReadWithDelay : public ActionFlowA, public ActionRead, public ActionWithDelay
{
// implementation of the full flow of a read command with delay that does Flow A.
};
class ActionFlowBReadWithDelay : public ActionFlowB, public ActionRead, public ActionWithDelay {/*...*/};
//...
当然,我会遵守任何两个动作(继承自 Action 类)都不会实现相同的方法。
Case 2:我在我的系统中实现了“命令”的复合设计模式。一个命令可以读取、写入、删除等。我还希望有一个命令序列,也可以读取、写入、删除等。一个命令序列可以包含其他命令序列。
所以我有如下的设计:
class CommandAbstraction
{
CommandAbstraction(){};
~CommandAbstraction()=0;
void Read()=0;
void Write()=0;
void Restore()=0;
bool IsWritten() {/*implemented*/};
// and other implemented functions
};
class OneCommand : public virtual CommandAbstraction
{
// implement Read, Write, Restore
};
class CompositeCommand : public virtual CommandAbstraction
{
// implement Read, Write, Restore
};
此外,我还有一种特殊的命令,“现代”命令。单一命令和复合命令都可以是现代命令。 “现代”向一个命令和复合命令添加了一系列属性(这两个命令的属性大多相同)。我希望能够保存一个指向 CommandAbstraction 的指针,并根据所需的命令类型对其进行初始化(通过 new )。所以我想做以下设计(除了上面的之外):
class ModernCommand : public virtual CommandAbstraction
{
~ModernCommand()=0;
void SetModernPropertyA(){/*...*/}
void ExecModernSomething(){/*...*/}
void ModernSomethingElse()=0;
};
class OneModernCommand : public OneCommand, public ModernCommand
{
void ModernSomethingElse() {/*...*/};
// ... few methods specific for OneModernCommand
};
class CompositeModernCommand : public CompositeCommand, public ModernCommand
{
void ModernSomethingElse() {/*...*/};
// ... few methods specific for CompositeModernCommand
};
再次,我将确保从 CommandAbstraction 类继承的两个类不会实现相同的方法。
谢谢。