删除条件代码作为策略模式的一部分

时间:2014-06-04 21:18:13

标签: java design-patterns strategy-pattern

我有一些代码根据条件执行不同的逻辑。但是使用策略模式不允许删除条件代码?使用Google这似乎是使用策略模式的常见结果:https://www.google.ie/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=removing%20if%20statements%20strategy%20pattern

例如:

class Cond {
 if(cond1){
  perform1
 }
 if(cond2){
  perform1
 }
}

策略模式:

interface Performer {
   doWork
}

class Perform1 implements Performer {
  doWork
}

class Perform2 implements Performer {
  doWork
}

class Cond {
 if(cond1){
  new Perform1.doWork
 }
 if(cond2){
  new Perform2.doWork
 }
}

策略模式更关注开放封闭原则而不是实际删除条件代码?也不是条件码自然发生的编程?

4 个答案:

答案 0 :(得分:0)

这对我来说并不像策略模式实现那样。我理解它是伪代码,但我不遵循它。这个例子更简单,实际上在执行策略时不需要编写条件:

// Strategy Interface
public interface CompressionStrategy {
    public void compressFiles(ArrayList<File> files);
}

public class ZipCompressionStrategy implements CompressionStrategy {
    public void compressFiles(ArrayList<File> files) {
        // using ZIP approach
    }
}

public class RarCompressionStrategy implements CompressionStrategy {
    public void compressFiles(ArrayList<File> files) {
        // using RAR approach
    }
}

public class CompressionContext {
    private CompressionStrategy strategy;

    // this can be set at runtime by the application preferences
    public void setCompressionStrategy(CompressionStrategy strategy) {
        this.strategy = strategy;
    }

    // use the strategy
    public void createArchive(ArrayList<File> files) {
        strategy.compressFiles(files); // <-- with stragtegy set, notice that 
                                       // no conditionals are required here.
    }
}

public class Client {

    public static void main(String[] args)
       {
          CompressionContext ctx = new CompressionContext(); 
         //we could assume context is already set by preferences 
          ctx.setCompressionStrategy(new ZipCompressionStrategy());     
         //get a list of files 
        ...
         ctx.createArchive(fileList);    
       }
}

答案 1 :(得分:0)

策略模式仅封装差异,您仍需要在执行期间分配正确的行为。

您可以将策略附加到请求工作的对象,而不是设置条件标志。

在这里看看如何转换具有多态性的开关:http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism

答案 2 :(得分:0)

是的,条件是编程的基本和固有元素。您不能,也没有任何理由想要删除条件代码&#34;来自任何非平凡的计划。 实现条件代码有不同的方法,有些情况下有些方法优于其他方式,但坦白说,完全删除它的概念是无意义的。

策略模式只是封装 - 具体来说,它是关于封装算法:看看你给出的两个例子之间的区别。您避免删除了所有条件,两个示例中都有相同的两个if语句。唯一的区别是,在后者中,您已将算法封装在类中。

答案 3 :(得分:0)

你可能想要一些与责任链类似的东西(c#sorry)

interface Performer {
    bool CanHandle(/* criteria/lambda */);
    void DoWork();
 }

 class Cond
 {
    void Do()
    {
         Performer strategy=strategies.Find(s=>s.CanHandle(/* condition */));
         if (strategy==null) throw new NoStrategyAvailable();
         strategy.DoWork();

     }
 }

可能不是应用最纯粹的策略模式,但是它非常易于维护:如果您使用反射从项目中获取所有策略,您只需添加一个新的策略实现,它就可以正常工作。