2010-04-21 137 views
2

我想获得关于以下三种设计模式的stackoverflow社区的意见。首先是实现继承;第二个是接口继承;第三个是中间地带。我的具体问题是:哪个最好?实现/接口继承设计问题

实现继承:

class Base { 
    X x() const = 0; 
    void UpdateX(A a) { y_ = g(a); } 
    Y y_; 
} 

class Derived: Base { 
    X x() const { return f(y_); } 
} 

接口继承:

class Base { 
    X x() const = 0; 
    void UpdateX(A a) = 0; 
} 

class Derived: Base { 
    X x() const { return x_; } 
    void UpdateX(A a) { x_ = f(g(a)); } 
    X x_; 
} 

中间地带:

class Base { 
    X x() const { return x_; } 
    void UpdateX(A a) = 0; 
    X x_; 
} 

class Derived: Base { 
    void UpdateX(A a) { x_ = f(g(a)); } 
} 

我知道很多人喜欢接口继承实现继承。然而,后者的优点是,通过指向Base的指针,可以内联x(),并且可以静态计算x_的地址。

回答

0

我会说没有任何一项技术比其他技术本身更好更好。根据使用环境的不同,它们都适用于不同的场景。

如果您正在实施Composite Pattern并且大多数类将使用相同的实现,那么实现继承可能是一条可行的路。它将允许您改进那些需要它的类的实现,同时为那些不需要的类共享代码。

如果您正在实施Visitor Pattern,其中每个类的方法实现可能完全不同,那么接口继承可能最有意义。在这种情况下,基类实现可能只能由单个类使用。

如果您继承的项目不是使用面向对象技术设计的,那么我可以看到您的中间示例很有用。也许你需要在添加新功能的同时重构它,并且可以使用它作为获取遗留代码与使用面向对象设计的新代码交互的方式。这是比实际的“最佳实践”更妥协的做法,但我们都必须让它们运送产品......如果我能想到一个更好/更具体的例子,我会发布它。

0

如果有多个派生类,所有派生类在输入上使用g(a)转换,那么我会选择第一个选项,以避免重复代码。我认为这是一个比优化元素寻址更高的目标。