与空方法默认实现设计模式(Design pattern for default implementa

2019-07-31 22:50发布

是否有一个说明,提供了非抽象的默认实现实现全部或部分的接口上的方法与空,NO-OP的实施方案具体的设计模式 。 这正与实施,他们自己可能不需要/使用方法的负担减轻的子类的意图来完成:

public interface MyInterface {
    public void doThis();
    public void doThat();
    public void done();
}

public class MyClass implements MyInterface {
    public void doThis() {
        // NO-OP
    }
    public void doThat() {
        // NO-OP
    }
    public void done() {
        // Some standard implementation
    }
}

public class MuSubClass extends MyClass {
    public void doThat() {
        // Subclass only cares about doThat()
    }
}

我已经看到了这种模式使用的次数,包括Java的的DefaultHandler在SAX框架 ,并MouseAdapter 。 在萨姆情况下,这种类被称为适配器,但我是适配器模式两种不同的接口之间进行转换的印象。

由于在这些情况下,只有一个声明接口,被翻译成该接口的一个未定义的子集 - 我不是如何,这是在适配器模式的精神清晰。

此外,我不太看这个如何遵守NullObject模式 ,无论是考虑到一些方法可以有实现,而NullObject是传统的单。

Answer 1:

有没有设计模式的默认实现。

我通常追加DoNothing前缀类的名称。 根据它的意图,我也使用BaseDefault (后者被广泛使用)。 也许MouseAdapter应该叫DefaultMouseListener

在你关心的情况下,可以系统地存根用一个简单的界面DynamicProxy ,必须(对对象空,0数字,等等)返回只有一个“好”的默认值。

顺便说一句,这是一个非常好的问题。

编辑

此外,这既不是一个存根或一个模拟 :也许它可以与存根混淆但目的是不同的。



Answer 2:

我已经看到了这样的设计在春用,他们有一类名为FlowExecutionListenerAdapter从而节省您实现所有FlowExecutionListener操作。

但是,它听起来像空对象模式了。 但是我觉得它坐落在适配器世界纯粹是更好,因为它允许你只实现你想要的位改变接口的水煤浆...但它的一个艰难的一个。

我敢肯定,这个问题以前有人问?

这听起来类似的没有? 可能是值得一读。



Answer 3:

它也可用于在Swing(WindowAdapter的,它实现的WindowListener)。 这只是一个方便的转接器,你只需要定义这样1-2方法有一个有用的WindowListener。 这确实是适配器模式的一个实例,还示出了抽象类的电源。 它甚至来说明为什么实现多继承是非常有用的,有时一个例子。

至于常规设计模式,在Temlate方法,你可以定义钩子操作,这可能会被覆盖(与抽象的方法,它必须是),但默认的行为(通常是NO-OP)是有意义了。



Answer 4:

您应该按照不同的设计原则: 接口隔离原则

该接口分离原则规定,客户不应该被强迫来实现它们不使用的接口。 而不是一个脂肪接口许多小接口基于的方法的组,每组一个服务一个子模块优选的。

你不应该实施更多,你不应该实现更少

看一看相关SE问题的更多细节。

接口隔离原则

接口隔离Principle-计划到接口



Answer 5:

大的问题。

我已经开始使用NoOp作为该模式的类名前缀。 这是个简短,明确,并没有过载(如Empty [包含什么?], Null [Null对象模式,这是不同的?] Abstract [它是否提供了一些实施?],或Base [它是否提供了一些实施?]) 。

当我有一个第三方的API,它复杂的操作过程中提供的“钩子”为isntrumentation我可以写类的这种风格。 考虑由图书馆提供的以下两类:

public class LongRunningActionRunner {
    public void runSomethingLong(DecisionListener cdh) {
        // ...
    }
}

public interface DecisionListener {
    public void beforeFooHook();
    public void afterFooHook();
    public void beforeBarHook();
    public void afterBarHook();
    public void beforeBazHook();
    public void afterBazHook();
}

在这种情况下,你可能会使用这种模式像这样作为一个类:

public class NoOpDecisionListener implements DecisionListener {
    @Override public Something beforeFooHook() {}
    @Override public Something afterFooHook() {}
    @Override public Something beforeBarHook() {}
    @Override public Something afterBarHook() {}
    @Override public Something beforeBazHook() {}
    @Override public Something afterBazHook() {}
}


Answer 6:

这种模式是旧版本的Java的流行。 它是Java 7的替代默认的接口方法 。

乔希布洛赫称之为一个框架实现 。 虽然框架实现通常是抽象的,你不必强迫客户创造一个子类,如果骨架本身就足够了。

我同意前面的答案指明了接口隔离原则 。 需要有一个框架实现可指示界面代码味道太“胖”,并且可以尝试做一个以上的作业。 分裂的界面,优选在这种情况下,以创建与伪晶片或空操作逻辑骨干实现。



Answer 7:

对我来说,这似乎是最接近特殊情况或空对象模式。

您的更新建议类似的东西模板方法希望你没有调用每个模板方法如一个单一的方法

public void doEverything()
{
  doThis();
  doThat();
  done();
}


Answer 8:

你问的是空对象模式 ?

继你编辑的MyClass对象无非是默认的多实行。 我不认为有这么描述它的任何具体的设计模式。



Answer 9:

我相信Martin Fowler的会调用这个空对象模式。 在他的书中重构[1],马丁介绍了空对象作为这样的:

多态的本质是不是要求的对象是什么类型,然后调用基础上,回答一些问题,你刚才援引的行为。 对象,根据其种类,做正确的事。 其中一个不太直观地做到这一点的是,你必须在一个字段为空值。

他后来补充说,“当许多客户希望做同样的事情你受益,他们可以简单地依赖于默认为空行为。” 他还介绍了需要变种行为客户的ISNULL()方法。

我会同意,我有时会看到一个(通常是抽象)实现所谓的适配器。 例如,在Android框架, AnimatorListenerAdapter (源代码这里 )被描述为:

这个适配器类提供的从Animator.AnimatorListener方法的空实现。 即只关心这个监听器的方法的子集的任何定制的监听器可以简单地继承,而不是直接实现此接口的适配器类。

[1]“重构:改善现有代码的设计,”第9章,“简化条件表达式”,“介绍空对象”。



文章来源: Design pattern for default implementation with empty methods