OO:新类的实现需要附加参数

时间:2019-03-22 18:36:06

标签: java oop

假设我有一个如下所示的界面

public interface ConditionChecker {
    boolean isInCondition(Person p);
}

我想创建一个实现上述接口的新类,但是我需要使用另一个参数来实现一个函数

public class MacroConditionChecker implements ConditionChecker {
    public boolean isInCondition(Person p, MacroView mv);
}

两个问题:
一:如果我将接口签名更改为boolean isInCondition(Person p, MacroView mv);,则需要更新所有实现ConditionChecker的类
二:我希望ConditionChecker的使用者按原样调用isInCondition

我认为这意味着:

public class MacroConditionChecker implements ConditionChecker {
    private static final MacroView mv;
    public MacroConditionChecker(MacroView mv) {
        this.mv = mv;
    }
    public boolean isInCondition(Person p){
        // now i have access to MacroView
    }
}

因此,我唯一需要做的更改是在我决定使用MacroConditionChecker时并且对isInCondition的调用未更改

我走对了吗?还是有其他方法可以做到这一点?

或者我应该将MacroView分离为自己的界面

public class MacroConditionChecker implements ConditionChecker implements MacroView

3 个答案:

答案 0 :(得分:1)

鉴于MacroConditionChecker不尊重ConditionChecker签名,那么实现它有什么意义呢?

也许更好的方法是将MacroConditionChecker class转换为扩展 interface

ConditionChecker
interface MacroConditionChecker extends ConditionChecker {
   boolean isInCondition(final Person person, final MacroView macroView);
}

然后提供默认/简单的实现(或您需要的任何内容)

class SimpleMacroConditionChecker implements MacroConditionChecker {
   public boolean isInCondition(final Person person, final MacroView macroView) {
      ...
   }
}

需要使用MacroView检查条件的人只会接受MacroConditionChecker

public boolean check(final MacroConditionChecker checker) {
   return checker.isInCondition(this.person, this.macroView);
}

我个人认为它们是两个完全分开的interface,但是扩展方法仍然不错。
谨慎选择,尤其是如果它们会在许多地方使用时。

答案 1 :(得分:1)

由于接口仅要求您实现给定的方法,因此您可以使用所需的参数重载该方法,并且在传递额外的参数时将运行适当的实现。

public class MacroConditionChecker implements ConditionChecker {
    boolean isInCondition(Person p) {};
    public boolean isInCondition(Person p, MacroView mv) {};
}

答案 2 :(得分:1)

ConditionChecker提醒Command design pattern。来自链接页面的评论:

  

命令将调用操作的对象从一个对象中分离出来   知道如何执行。为了实现这种分离,设计师   创建一个抽象基类,该基类将接收器(对象)映射为   一个动作(指向成员函数的指针)。基类包含一个   只需在接收方上调用操作的execute()方法。

这正是您所需要的。如果您只需要检查Person对象的内部状态就足够了。当您要使用外部Person检查API对象时,可以创建将构造函数中的外部API与方法中的Person对象绑定的实现。简单的例子:

import java.util.ArrayList;
import java.util.List;

public class DesignPatterns {

    public static void main(String[] args) {
        List<ConditionChecker> checkers = new ArrayList<>();
        checkers.add(person -> person != null);
        checkers.add(person -> person.getName() != null);
        checkers.add(person -> person.getName().length() > 0);
        checkers.add(new MacroViewConditionChecker(new MacroView()));
        checkers.add(new RestApiConditionChecker(new RestApi()));

        Person person = new Person();
        person.setName("Name");

        for (ConditionChecker checker : checkers) {
            System.out.println(checker.isInCondition(person));
        }
    }
}

interface ConditionChecker {

    boolean isInCondition(Person person);
}

class MacroViewConditionChecker implements ConditionChecker {

    private final MacroView macroView;

    public MacroViewConditionChecker(MacroView macroView) {
        this.macroView = macroView;
    }

    @Override
    public boolean isInCondition(Person person) {
        return macroView != null;
    }
}

class MacroView {
}

class RestApiConditionChecker implements ConditionChecker {

    private final RestApi restApi;

    public RestApiConditionChecker(RestApi restApi) {
        this.restApi = restApi;
    }

    @Override
    public boolean isInCondition(Person person) {
        return restApi.checkName(person.getName());
    }
}

class RestApi {

    public boolean checkName(String name) {
        System.out.println("Validate name ...");
        System.out.println(name + " is valid");

        return true;
    }
}

class Person {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

您可以将此模式与Chain of Responsibility一起使用。此方法不会将Person对象与任何实现绑定。此绑定是在特定的ConditionChecker实现中完成的,可以轻松交换。