【问题标题】:instanceof versus redirecting methodsinstanceof 与重定向方法
【发布时间】:2015-12-30 11:41:26
【问题描述】:

在重构期间,我需要通过添加额外的参数来扩展现有接口。现在有很多老类实现了无参版本,也有一些新类实现了有参版本:

void exec(int parameter);

void exec();

最终,我需要接受实现这两个接口的类到同一个集合中,然后在同一个方法中处理。似乎有两种可能的方法:

\1。使用instanceof

int parameter = ...
if (a instanceof NewInterface) 
    ((NewInterface) a).exec(parameter);
else
    ((OldInterface) a).exec();

这样做的好处是NewInterfaceOldInterface可以是独立的接口。当开发者编写一个新类时,可能会更明显地重写哪些方法,而重写错误的方法会导致编译时错误。

\2。使用定义了两个方法的单一接口和从一个方法重定向到另一个方法的父抽象类:

abstract class Common {
    abstract void exec();
    void exec(int param) { exec(); }
}

这可以避免instanceof 在某些讨论中被认为是不好的,但现在在每个新类中我们必须添加一个看起来很奇怪的存根:

 // This is not used anymore
 void exec() { };
 // This is a real functionality 
 void exec(int param) { ...

看起来也不是最好的设计,尤其是考虑到错误调用此存根的可能性。

我应该使用第三种方法,还是在使用 instanceof 合理的情况下是这种情况?

【问题讨论】:

  • 您是否有权访问使用您的方法的所有代码库?
  • 是的,但我宁愿避免在许多不需要它的方法的声明中大量添加未使用的参数。的,如果这真的是唯一正确的方法,这将是可能的答案。
  • @h22 但这是正确的做法。接口契约说 exec() 接受一个参数,由实现决定对它做些什么,或者忽略它。
  • 保留两者(你的第二个想法)但标记旧方法deprecated
  • @OldCurmudgeon 听起来旧界面并没有真正被弃用。如果大量代码从不需要指定这个新参数,那么听起来它应该是 API 的一部分。 h22 现有代码是实际接口还是抽象类?如果它实际上是一个接口,那么您可以使用默认方法。

标签: java polymorphism refactoring


【解决方案1】:

如果您使用的是 Java 8,您可以使用 default implementation 在接口中轻松实现它:

public interface MyInterface {

    void exec();

    default void exec(int param) {
        exec();
    }
}

exec(int) 自然可以被具体类覆盖。

另一种解决方案是使用NewInterface extends OldInterface。然后新类实现NewInterface#exec(int)OldInterface#exec(),新客户端可以选择调用哪个方法,老客户端只知道OldInterface

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 2012-02-22
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2011-06-26
    • 1970-01-01
    相关资源
    最近更新 更多