如何在限制性环境中实施工厂模式?

时间:2013-10-31 09:11:42

标签: java design-patterns

我有一个课程,比如Aextends B。 我既不能改变类的名称,也不能改变扩展名。

但是,A中有一种方法,比方说doSomething(我无法重命名)。

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

考虑到所有这些限制,你如何根据旗帜建议在doSomething中处理fork?

由于

4 个答案:

答案 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?如果可以的话,通常最好避免条件并对类内部策略的构造进行硬编码。

您无需触及基类,只需使用其他实现扩展它。