我对使用哪种模式设计以下场景感到困惑,
Interface GearBox {
int upshift();
int downshift();
int reverse();
}
AutoGearBox implements GearBox{...}
ManualGearBox implements GearBox{...}
现在我想将DualClutchGearBox添加到层次结构中。以前的所有变速箱都是单离合器。我该怎么做呢?
使用装饰器 - >
DualClutchDecorator implements GearBox{
DualClutchDecorator(GearBox box){...}
}
使用Bridge - >
GearBox{
GearBoxImpl impl;
....
}
AutoGearBox implements GearBox{...}
ManualGearBox implements GearBox{...}
abstract class GearBoxImpl{}
SingleClutchImpl extends GearBoxImpl{...}
DualClutchImpl extends GearBoxImpl{...}
哪一个更好,为什么?
答案 0 :(得分:5)
Decorator必须与想要装饰的对象的界面相匹配。考虑到这一点,您可以在不违反界面的情况下向装饰对象添加附加行为。请记住,装饰器的界面可以为您的对象提供额外的功能。
另一方面,桥梁没有这个限制。面向客户端的接口可以与底层的组件不同,并提供实现。它构成了客户端接口与实际实现之间的桥梁。
答案 1 :(得分:3)
我不确定我是否会使用这些模式中的任何一种。你有没有理由不想创建第3个具体类?
当您需要动态更改行为时,可以使用Decorator。我能想到的一个主要例子是Java的InputStreamReader。我可以为我需要的任何情况编写一个装饰的阅读器,它们符合相同的界面
// I need to read lines from a file
Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
// Or I want to read lines from a byte array and track the line numbers
Reader r = new LineNumberReader(new InputStreamReader(new ByteArrayInputStream(bytes)));
所以装饰器的想法是我可以通过添加装饰器来改变运行时的行为。根据我的理解,这不是你想做的事情。 DualClutch将表现出特定的行为,无需动态更改它。
我也没有看到Bridge的一个很好的案例,但我想这取决于你的具体情况。就像我说的那样,看起来DualClutch只会有静态行为,汽车会不会有。看起来像一个简单的具体类就可以解决这个问题。
答案 2 :(得分:1)
取决于。
您的界面是否从驱动程序的角度定义界面?您是否想要抽象出齿轮箱的常见功能(更换齿轮的能力!)?
请记住,自动和手动变速箱实际上没有完全相同的功能,因此可能无法共享相同的接口(例如,您可以在手动变速箱中直接从第5档切换到第3档,但是不是在大多数汽车上 - 而且汽车可能具有手动变速箱不需要的强制降档功能。)
相反,双离合器变速箱在接口方面可能与单离合器变速箱无法区分,仅在实施方面有所不同。