我有一个课程,比如A
,extends B
。
我既不能改变类的名称,也不能改变扩展名。
但是,A
中有一种方法,比方说doSomething
(我无法重命名)。
根据一个标志,在A
的构造函数中发送,我可以做某事或其他事情。
考虑到所有这些限制,你如何根据旗帜建议在doSomething中处理fork?
由于
答案 0 :(得分:1)
没有进一步的信息:
public Foo doSomething() {
if( flag ) {
return super.doSomething();
} else {
return doSomethingElse();
}
}
您可以使用策略模式,但除了您应用设计模式的感觉之外,它会添加几十行代码而没什么好处。
在方法调用中使用必要的间接,如果可能更慢。
答案 1 :(得分:0)
我认为您可以从以下两个选项中选择一个:
根据标志将标志和doSomething
用于2个内部方法。例如:
public class A extends B {
private boolean forkFlag;
public A (boolean forkFlag) {
this.forkFlag = forkFlag;
}
public void doSomething() {
if (forkFlag) {
doSomething1();
} else {
doSomething2();
}
}
private void doSomething1() { ... }
private void doSomething2() { ... }
}
创建策略实施:
public class A extends B {
private boolean forkFlag;
private Runnable doSomethingImpl;
public A (boolean forkFlag) {
if(forkFlag) {
doSomethingImpl = new DoSomethingImpl1();
} else {
doSomethingImpl = new DoSomethingImpl2();
}
}
public void doSomething() {
doSomethingImpl.run();
}
}
public class DoSomethingImpl1 implements Runnable {
public void run() { ... }
}
public class DoSomethingImpl2 implements Runnable {
public void run() { ... }
}
在这两者之间做出决定取决于您的需求。如果这个fork很小,只是常规流程中的一个用例,我会选择第一个选项。如果你有可能需要第三次流程,我会选择策略模式并享受它所提供的解耦。
使用策略,您将能够从类外部注入所需的实现,并且只需更改构造函数即可完全不知道doSomething
的实现:
public A (Runnable doSomething) {
this.doSomething = doSomething;
}
注入模式可能是最优雅的,它将创建代码与实现的完全分离。此外,您可以将implements Runnable
更改为您自己public interface DoSomething
的更具体的界面,以使其更加强大。
答案 2 :(得分:0)
你必须在这里使用Strategy
模式
public A(boolean flag){
if(flag == true){
this.service = new DoSomethingStrategy();
}else{
this.service = new DoSomethingElseStrategy();
}
}
如果您的代码在逻辑上增长,最好使用Factory on构造函数:
public A(boolean flag){
this.service = DoSomethingFactory.getService(flag);
}
并复制DoSomethingFactory
;
最后是您的doSomething
方法
public void doSomething(){
this.service.doSomething();
}
并且您对doSomething的行为被封装到策略结构中。
答案 3 :(得分:0)
为什么不能创建另一个C类,它也扩展B并根据需要使用它而不是A?如果可以的话,通常最好避免条件并对类内部策略的构造进行硬编码。
您无需触及基类,只需使用其他实现扩展它。