Design pattern for default implementation with emp

2019-03-14 11:43发布

Is there a specific design pattern that describes the scenario where a non-abstract default implementation is provided that implements all or some of the methods on the interface with empty, NO-OP implementations. This being done with the intent of alleviating subclasses with the burden of implementing methods that they themselves may not need/use:

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()
    }
}

I have seen this pattern used a number of times including Java's DefaultHandler in the SAX framework, and MouseAdapter. In somes cases such classes are named as Adaptors, but I was under the impression that the adapter pattern translates between two different interfaces.

Given that in these instances there is only one declared interface that is being translated to an undefined subset of that interface - I am not clear on how this is in the spirit of the adapter pattern.

Furthermore, I don't quite see how this adheres to the NullObject pattern either, given that some methods could have an implementation, and the NullObject is traditionally a singleton.

9条回答
劫难
2楼-- · 2019-03-14 11:45

To me this seems closest to the Special Case or Null Object pattern.

Your updates suggest something similar to Template Method expect that you don't have a single method that calls each template method e.g.

public void doEverything()
{
  doThis();
  doThat();
  done();
}
查看更多
Ridiculous、
3楼-- · 2019-03-14 11:53

Great question.

I have started using NoOp as a class name prefix for this pattern. It's short, clear, and not overloaded (like Empty [contains nothing?], Null [Null Object pattern, which is different?], Abstract [Does it provide some implementation?], or Base [Does it provide some implementation?]).

I may write this style of class when I have a third-party API which provides "Hooks" for isntrumentation during a complex operation. Consider the following two classes provided by a library:

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();
}

In this case, you might right a class using this pattern like this:

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() {}
}
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-03-14 11:57

You should follow different design principle : interface-segregation principle

The Interface Segregation Principle states that clients should not be forced to implement interfaces they don't use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one sub module.

You should not implement MORE And you should not implement LESS

Have a look at related SE questions for more details.

The Interface Segregation Principle

Interface Segregation Principle- Program to an interface

查看更多
迷人小祖宗
5楼-- · 2019-03-14 11:57

Are you asking about the Null Object Pattern?

Further to your edit, the MyClass object is nothing more than a default implemenation. I don't think there's any particular design pattern that describes it.

查看更多
ら.Afraid
6楼-- · 2019-03-14 11:58

This pattern was prevalent in older versions of Java. It is the Java 7 alternative to default methods in interfaces.

Josh Bloch calls it a skeletal implementation. While a skeletal implementation is typically abstract, you needn't force clients to create a subclass if the skeleton itself is sufficient.

I agree with the previous answer pointing out the Interface Segregation Principle. The need for a skeletal implementation can be a code smell indicating an interface is too "fat" and may be trying to do more than one job. Splitting up the interface is preferable in this scenario to creating a skeletal implementation with dummy or noop logic.

查看更多
来,给爷笑一个
7楼-- · 2019-03-14 12:03

It's also used in Swing (WindowAdapter, which implements WindowListener). It's only a convenience adapter, you only have to define 1-2 methods in this way to have a useful windowlistener. This is indeed an instance of the Adapter pattern, also shows the power of the abstract classes. It's even an example to illustrate why multiple implementation inheritance is useful sometimes.

As for the regular Design Patterns, in the Temlate Method you can define hook operations, which may be overriden (unlike abstract methods, which must be), but the default behaviour (usually the NO-OP) is meaningful too.

查看更多
登录 后发表回答