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 12:05

There are no design patterns for default implementation.

I usually append DoNothing prefix to the name of class. Depending on it's intent I use also Base or Default (the latter is widely used). Probably MouseAdapter should be called DefaultMouseListener.

In the case you care, you can stub systematically an interface with a simple DynamicProxy, you must return only a "nice" default value (null for Object, 0 for numeric, etc).

BTW this is a very good question.

EDIT

Furthermore this is neither a Stub or a Mock: maybe it can be confused with a Stub but the intent is different.

查看更多
再贱就再见
3楼-- · 2019-03-14 12:07

I believe Martin Fowler would call this a null object pattern. In his Refactoring book[1], Martin introduces null objects as such:

The essence of polymorphism is that instead of asking an object what type it is and then invoking some behavior based on the answer, you just invoke the behavior. The object, depending on its type, does the right thing. One of the less intuitive places to do this is where you have a null value in a field.

He later adds, "You benefit when many clients want to do the same thing; they can simply rely on the default null behavior." He also introduces an isNull() method for clients requiring variant behaviors.

I would agree that I sometimes see a (often abstract) implementation called an adapter. For example, in the Android framework, AnimatorListenerAdapter (source code here) is described as:

This adapter class provides empty implementations of the methods from Animator.AnimatorListener. Any custom listener that cares only about a subset of the methods of this listener can simply subclass this adapter class instead of implementing the interface directly.

[1] "Refactoring: Improving the Design of Existing Code," Chapter 9, "Simplifying Conditional Expressions," "Introduce Null Object."

查看更多
一夜七次
4楼-- · 2019-03-14 12:09

I have seen this design used in spring where they have a class named FlowExecutionListenerAdapter which saves you implementing all the FlowExecutionListener operations.

However, it does sound like the Null Object Pattern too. However I feel it sits better in the Adapter world purely because it changing the behavour of the interface by allowing you only to implement the bit you want...but its a tough one.

I'm sure this question has been asked before?

This sounds similar no? might be worth a read.

查看更多
登录 后发表回答