1

我有一堂课,比如说A,那个extends B。我既不能改变类名,也不能改变扩展名。

但是,A假设中有一个方法doSomething(我无法重命名)。

根据一个标志,在构造函数中发送的AI 可以做某事或其他事情。

鉴于所有这些限制,您建议如何根据标志处理 doSomething 中的分叉?

谢谢

4

4 回答 4

1

没有更多信息:

public Foo doSomething() {
   if( flag ) {
       return super.doSomething();
   } else {
       return doSomethingElse();
   }
}

您可以使用策略模式,但它会添加数十行代码,除了您应用设计模式的感觉之外几乎没有什么好处。

在方法调用中使用必要的间接性,if 甚至可能会更慢。

于 2013-10-31T09:16:35.697 回答
0

You can choose one of 2 options in my opinion:

  • Use the flag and for doSomething into 2 inner methods according to the flag. For example:

    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()  { ... }
    }
    
  • Create a strategy implementation:

    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() { ... }
    }
    

Deciding between those 2 depends on your needs. If this fork is something minor, just a use case in a regular flow, I'd go with the first option. If there's a chance that you might need to have a third flow I'd go with the strategy pattern and enjoy the decoupling it provides.

With strategy you'll be able to inject the implementation you want from outside the class and be totally unaware of the implementation of doSomething just by changing the constructor:

public A (Runnable doSomething) {
   this.doSomething = doSomething;
}

The injection pattern is probably the most elegant and will create a complete decoupling of your code from the implementation. Also, you might change the implements Runnable into a more specific interface of your own public interface DoSomething to make it more robust.

于 2013-10-31T09:15:52.270 回答
0

你必须在Strategy这里使用模式

public A(boolean flag){
    if(flag == true){
        this.service = new DoSomethingStrategy();
    }else{
        this.service = new DoSomethingElseStrategy();
    }
}

如果您的代码在逻辑上增长,最好在构造函数上使用工厂:

public A(boolean flag){
    this.service = DoSomethingFactory.getService(flag);
}

并复制里面的代码DoSomethingFactory

最后在你的doSomething方法上

public void doSomething(){
    this.service.doSomething();
}

你对 doSomething 的行为被封装到一个策略结构中。

于 2013-10-31T09:16:22.807 回答
0

为什么不能创建另一个类 C 来扩展 B 并根据需要使用它而不是 A?如果可以的话,通常最好避免条件和硬编码类内的策略构造。

您不需要接触基类,只需使用另一个实现扩展它。

于 2013-10-31T09:26:34.467 回答