假设您有IBuilding和IDwelling接口,以及实现两者的类House。它封装了建筑物和住宅:
class House implements IBuilding, IDwelling
{
private IBuilding building;
private IDwelling dwelling;
}
如果IBuilding和IDwelling各自定义了15种方法,那么在House类中编写30个方法,只转发到门或窗口的方法是否正常?
这看起来非常非常乏味。这真的是一件事吗?很多资源表明,是的,这就是你要做的,但是他们都使用超简单的例子,这些例子并不像我想象的那样令人生畏。
还是有一些更聪明的方式来构思我不知道的吗?
答案 0 :(得分:1)
这是否必须这么乏味?没有。有更聪明的方法吗?是。
我可以想出为什么要使用这个构图有三个原因:
在这三个中,仅案例#2可能要求您将包装类中的每个调用转发到包装类。即便如此,有些语言可能允许您创建一个所谓的“动态”代理,这样您就不必为您的内部类中的每个方法创建一个方法来转发调用。例如,在Java中它被称为Dynamic Proxy Class
,在PHP中它是神奇的__call()
方法。
另一件事是,你在问题中所描述的情况在实践中非常罕见。
<强>更新强>
这里的主要问题是,如果我们希望包装类实现包装类的接口,那么使用PHP时,__call()
方法确实无法帮助我们。如果界面的方法很少,那么实现它们并不困难,但如果它有15个呢?我认为,这个问题不是构图的问题,而是大接口的问题。要避免此类问题,您需要遵循Interface Segregation Principle。但有时候,如果您正在编写通用API,则很难遵循该原则。如果是这种情况,那么除了方法调用的一对一映射之外,没有别的东西可以做了。遗憾。
答案 1 :(得分:0)
虽然它似乎是一个极端的例子,是的,组合是关于水平委托,而且大多数时候你都有明确的编程委派。根据您编程的语言,您可能会发现Traits就像一个很好的机制来实现水平构图,而无需编写“胶水代码”。您可能会发现论文Traits: Composable Units of Behaviour是一本很好的解读,解释了垂直重用的问题,以及为什么像特征这样的方法可以替代。
HTH