结合Java策略模式中的策略

时间:2014-01-07 13:24:43

标签: java design-patterns strategy-pattern

以下示例无耻地从java.dzone.com中删除,并根据我的需要进行了修改:

我们的界面:

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

我们的第一次实施

public class GZipCompressionStrategy implements CompressionStrategy
{

   public File compressFiles(ArrayList<File> files)
   {
     //using GZIP approach
     return archive;
   }

}

我们的第二次实施:

public class TarCompressionStrategy implements CompressionStrategy
{

   public File compressFiles(ArrayList<File> files)
   {
     //using TAR approach
     return archive;
   }

}

这是给出的用途:

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 File createArchive(ArrayList<File> files) 
   {
        strategy.compressFiles(files);
   }

}

使用Main方法的客户端类

public class Client
{

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

感觉很乱,因为:

  1. 我每次都要重置策略
  2. 两种策略可能兼容也可能不兼容(按此顺序,例如Tar对GZipped文件有意义吗?)
  3. 原则上创建第三个TARGZipStrategy类是正常的,但是如果我们有10个策略允许每个其他类策略成为有效的XXXCombinedStrategy方法的一部分,那么我们将有~35个不同的类。
  4. 有没有一种巧妙的方法可以在这种模式中顺序地任意运行多个策略?例如,如果我想在最后创建一个.tar.gzip文件?

    我想说的是将两种策略合二为一的巧妙方法?

    我觉得我正在做的事情应该有一些简洁的解决方案,我不想重新发明轮子,同时我也不想过于依赖模式。

3 个答案:

答案 0 :(得分:8)

您可以创建JoinedCompressionStrategy

class JoinedCompressionStrategy implements CompressionStrategy {

    private final CompressionStrategy s0;
    private final CompressionStrategy s1;

    public JoinedCompressionStrategy(CompressionStrategy s0, CompressionStrategy s1) {
        this.s0 = s0;
        this.s1 = s1;
    }

    public File compressFiles(ArrayList<File> files) {
        File archive = s0.compressFiles(files);
        return s1.compressFiles(Arrays.asList(archive));
    }
}

答案 1 :(得分:4)

您可能正在寻找decorator pattern实施。此模式的目的是动态地向对象添加其他职责。权衡是你也会得到一个子类的爆炸。

代码示例:

通用界面。

   public interface CompressionStrategy{
       File compressFiles(List<File> files);
   }

所有文件的基本压缩。

public class CompressionBase implements CompressionStrategy{

    @Override
    public File compressFiles(List<File> files)) {
        //return default compression
    }

}

装饰者抽象类

public abstract class AbstractCompressionDecorator implements CompressionStrategy{

    private final CompressionStrategy decoratee;

    /**
     * @param decoratee
     */
    public AbstractCompressionDecorator(CompressionStrategy decoratee) {
        super();
        this.decoratee = decoratee;
    }

    @Override
    public File compressFiles(List<File> files) {
        File file = decoratee.compressFiles(files); 
        return compressFilesToAnotherFormat(file);
    }

    protected abstract File compressFilesToAnotherFormat(File file);


}

和装饰器具体类。

public class TarCompression extends AbstractCompressionDecorator {

    public TarCompression (CompressionStrategy compressionStrategy) {
            super(compressionStrategy);
    }

@Override
protected File compressFilesToAnotherFormat(File file) {
    // tar compression logic here;
}

}

Zip压缩

 public class ZipCompression extends AbstractCompressionDecorator {

    public ZipCompression (CompressionStrategy compressionStrategy) {
            super(compressionStrategy);
    }

@Override
protected File compressFilesToAnotherFormat(File file) {
    // zip compression logic here;
}

和一个简单的工厂来创建对象

public final class CompressionFactory {

    private CompressionFactory (){}

    public static CompressionStrategy create(String extension){

        CompressionStrategy compressionStrategy = new CompressionBase();        

            if(extension.contains("zip")){
               compressionStrategy = new ZipCompression(compressionStrategy);
            }else if(extension.contains("tar.gzip")){
               compressionStrategy = new TarCompression(new GzipCompression(compressionStrategy));
            }

        return compressionStrategy ;
    }
}

然后在客户端代码中你只需写这个。

CompressionStrategy compressionStrategy = CompressionFactory.create("tar.gzip");
File file = compressionStrategy.compressFiles(files);

答案 2 :(得分:0)

public class TgzCompressionStrategy implements CompressionStrategy
{
     TarCompressionStrategy tar = new TarCompressionStrategy();
     ZipCompressionStrategy zip = new ZipCompressionStrategy();

    public File compressFiles(ArrayList<File> files)
    {
        File archive = tar.compressFiles(files);
        archive = zip.compressFiles(archive); // need to handle archive is not array list, but you can do that
        return archive;
    }

}