概述

结构与简单工厂模式相似,只是Factory换成了Context,简单工厂模式注重的是对象的创建,策略模式注重的是行为的变化。

Context类持有一个父类引用,传入不同的行为实例,则执行不同的行为。

在简单工厂模式中,当需要扩展或变更时,都需要改动工厂类,代码需要重新编译部署。

举例

不同查找算法

涉及的类:Context类、查找父类、二分查找类、顺序查找类

查找父类/接口

interface Search{
    public int search(int target, int[] array);
}

二分查找类

class SearchBinary implements Search{
    public int search(int target, int[] array){
        int index = 0;
        //二分查找算法
        return index;
    }
}

顺序查找类

class SearchSequence implements Search{
    public int search(int target, int[] array){
        int index = 0;
        //顺序查找算法
        return index;
    }
}

Context类

class SearchContext{
    private Search strategy;
    public SearchContext(Search strategy){
        this.strategy = strategy;
    }
    public int getResult(int target, int[] array){
        return strategy.search(target, array);
    }
}

客户端

SearchContext context = null;
String type= "binary";
switch(type){
    case "binary":
        context = new SearchContext(new SearchBinary());
        break;
    case "sequence":
        context = new SearchContext(new SearchSequence());
        break;
    }
}
int target = 1;
int[] array = new int[]{1,2,3};
int result = context.getResult(target, array);

分析

很明显,客户端出现了判断逻辑,那么我们可以将策略模式与简单工厂模式相结合:

class SearchContext{
    private Search strategy;
    public SearchContext(String type){  //参数由具体策略对象变为字符串
        switch(type){
            case "binary":
                strategy= new SearchBinary();
                break;
            case "sequence":
                strategy= new SearchSequence();
                break;
        }
    }
    public int getResult(int target, int[] array){
        return strategy.search(target, array);
    }
}

客户端的代码则简化成:

SearchContext context = new SearchContext("binary");

相比简单工厂模式中,客户端需要认识两个类Factory类和父类,策略模式只需认识一个Context类。

不过这样结合后,也就出现了简单工厂模式的弊端,因为在Context类中用到了switch,扩展时则需要改动Context类。这一问题可用反射来解决,在抽象工厂模式中将会讲到。