以下示例无耻地从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);
}
}
感觉很乱,因为:
有没有一种巧妙的方法可以在这种模式中顺序地任意运行多个策略?例如,如果我想在最后创建一个.tar.gzip
文件?
我想说的是将两种策略合二为一的巧妙方法?
我觉得我正在做的事情应该有一些简洁的解决方案,我不想重新发明轮子,同时我也不想过于依赖模式。
答案 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;
}
}