【问题标题】:Shared functionality in an abstract method抽象方法中的共享功能
【发布时间】:2014-06-13 19:14:57
【问题描述】:

我有一个设置图形项目标签的抽象方法。有不同类型的项目,它们都继承自具有“setLabel()”方法的抽象基类。

不同的物品在设置标签时做不同的事情,但最终都应该做同样的事情,这就是一系列的家务活。我知道我可以在基类中创建一个方法来完成这些琐事,然后在每个实现中调用它,但这很糟糕,因为如果我忘记从其中一个实现中调用它,它会创建一个错误.

有什么好的方法来构建它?

这是示例代码(我现在在 Java 中是如何做到的):

final public void _setLabel( String s ){
    if( s.trim().equals( "null" ) ) return;
    StringBuffer sbError = new StringBuffer();
    if( ! _setConstantValue( s, sbError ) ){
        Error.vShowError( "failed to set value: " + sbError );
        return;
    }
    sLabel = s;
    _update();
    _updateProperties();
    if( _isGroupMember() ) this.nodeGroup._update();
}

基类中有一个抽象方法“_setLabel”,所以我所有的子类都必须实现这个方法。方法中的最后三行始终相同:

_update();
_updateProperties();
if( _isGroupMember() ) this.nodeGroup._update();

现在,我只是将这些行复制并粘贴到每个实现中,但我希望它们以某种方式在基类中完成,因此我可以保证它们总是会发生。这些必须在 其他所有内容之后调用。

解决方案:

基于下面标记的答案(感谢 user3736255),解决方案是使用 C++ 中的非虚拟接口或 Java 中的模板方法(等效)。所以新的基类代码是:

final public void _setLabel( String s ){
    __setLabel( s );
    _update();
    _updateProperties();
    if( _isGroupMember() ) this.nodeGroup._update();
}

abstract protected void __setLabel( String s );

每个子类都实现了__setLabel方法,该方法被基类中的模板方法_setLabel调用。

【问题讨论】:

  • 您考虑过使用interface吗?
  • @CanadianDavid 太过分了,我只是想在这里设置一个标签。
  • 没有真正通用的方法来实现这一点。每种语言都将有自己的一组继承约束,如果可能的话,这些约束会改变实现方式。
  • 如果您希望所有答案都在 Java 中,为什么要用 C++ 标记它?
  • @CanadianDavid 因为我认为这两种语言的答案可能相同。

标签: java c++ oop design-patterns


【解决方案1】:

听起来您正在寻找非虚拟接口模式:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

【讨论】:

【解决方案2】:

也许:

class Base() {
   public:
   void setLabel();

   protected:
   virtual void doSetLabel();

   private:
   houseKeepingBefore();
   houseKeepingAfter();
}

void Base::setLabel() {
   houseKeepingBefore();
   doSetLabel();
   houseKeepingAfter();
}

但是,如果您有 houseKeepingInbetween,这不会解决您的问题。

【讨论】:

  • 之后我只需要做家务。我如何在 Java 中做到这一点?
【解决方案3】:

您是否要创建一个装饰器来扩展基础并使用图形项目的适当实例创建。调用家务活动是装饰者的责任。所有客户端都调用装饰器而不是实际的图形项。注意:我假设对图形项的所有调用都是通过基础中定义/声明的方法。

您也许还可以利用方面:http://en.wikipedia.org/wiki/Aspect-oriented_programming

【讨论】:

  • 不确定这是否能解决 OP 的问题,因为他们仍然需要记住在所有子类中装饰每个需要整理的方法。
  • 不确定装饰器是否是所有子类的代理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2014-12-24
  • 2015-08-02
  • 1970-01-01
  • 2010-11-03
  • 2023-04-09
相关资源
最近更新 更多