在我的一个项目中,我在几个地方使用以下模式:我有一个带有一堆方法的类A
,以及用一些指针构造的类B
A
的实例,仅为用户(不是A
实例的所有者)导出这些方法的子集。
class A
{
public:
void doStuff();
void doOtherStuff();
void doYetOtherStuff();
B getB()
{
return B(this);
}
};
class B
{
friend class A;
public:
void doStuff()
{
_a->doStuff();
}
void doOtherStuff()
{
_a->doOtherStuff();
}
private:
B(A* a) : _a(a) {}
A* _a;
};
例如,我的库可以创建A
的实例,并且可以将创建的B
实例(与A
相关联)传递给插件,仍然可以访问A
实例,虽然方式有限。
我对B
的设计模式名称感到困惑:它是外观,桥梁,适配器还是代理?或其他什么?
答案 0 :(得分:1)
在这种情况下,我建议检查Huston Design Patterns。在每个模式的最后,它引用了GoF并给出了当前模式和相关模式之间的差异。
例如,在代理上我们可以阅读:
适配器为其主题提供不同的界面。代理提供相同的接口。 Decorator提供增强的界面。 [GoF的。 P216]
因此,由于您限制接口,因此我们仍然需要检查Bridge和Facade。
如果我们检查适配器,我们会得到其他的块:
Bridge是预先设计的,让抽象和实现独立变化。改造适配器以使不相关的类一起工作。 [GoF,p161]
Facade定义了一个新接口,而Adapter重用了旧接口。请记住,Adapter使两个现有接口协同工作,而不是定义一个全新的接口。 [GoF,pp219]
然而,他们不是那么有说服力。此时它不太清楚,因为设计不是名称的唯一贡献者, intent 也很重要。 Facade是关于隐藏复杂性的,而Bridge是关于正交维度的去相关:这里都不适用。
因此我们留下 Adapter 。
答案 1 :(得分:0)
如果没有更多的背景,我会称之为代表。 B将责任委托给A。
这是Cocoa / UIKit编程中非常常见的模式,特别是如果A是一个相当抽象的类型 - 如果A只是一个任何类都可以实现的接口,情况会更好。
但是,如果您正在简化界面,特别是如果B的生命周期很短(只是为了简化对A的访问而存在),那么这是一个外观模式。
关于其他模式 - 没有一个被完全排除,但这是我的想法:
适配器通常会更改接口 - 也就是B的客户端要调用doStuff(),但是A有一些客户端不希望拥有的其他接口(可能更复杂或特定于域)处理,所以B使A的界面适应客户想要的界面。
代理通常涉及某些远程或不易访问或可实例化对象的表示; A的可访问性使得它看起来不像代理模式,但代理可以包装同名的API调用。
如果A的实施可能有所不同而且B从客户端隐藏了这一事实,这可能表明了一种策略模式。