假设我有一个如下所示的界面
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
答案 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
实现中完成的,可以轻松交换。