设计模式初探之策略模式

来源:互联网 发布:淘宝网男徒步凉鞋 编辑:程序博客网 时间:2024/06/06 00:53

         上周写了一篇静态工厂模式,现在讲一讲策略模式,同静态工厂模式一样,策略模式也是一种相对简单,容易理解的一种设计模式。首先看一下他的UML类图


从类图可以看出以下几个元素:

        策略接口:用于定义策略共有的方法操作。

        具体策略:策略具体的实现。

        上下文类:保存策略的引用,用于对策略操作。

下面有这么一个场景,程序员张三准备出去旅游,这时他可以选择多种交通工具,这么个场景,让我们用代码实现。我们最容易想到的就是以下这种实现方式,即将出行定义一个方法,根据传进来的参数选择不同的交通工具,将不同的交通工具定义成独立的方法。

这种方法当然能实现功能,但缺点非常明显

1、首先它开源封闭原则,即软件实体应该是可扩展的,而不可修改的。也就是对扩展是开放的,对修改是封闭的。显然,但我们要再加入交通工具是我们需要修改该类,新增新的交通工具的具体实现方法,还需修改switch。这种修改可能对已经实现的稳定的代码造成影响。

2、当策略变多时,即交通方法有很多种是,会让这个类变得臃肿,而且各种交通工具的实现代码混杂在一个类中,容易造成代码混乱,让后期维护,新增变得更难。

public Transportation{public void move(String method){switch(method){case "bike":bike();break;case "bus":bus();break;case plane:plane();break;}}private void bike(){System.out.print("骑自行车")};private void bus(){System.out.print("搭公交车")};private void plane(){System.out.print("搭飞机")};}

当然,直接将交通具体封装成工具类。让客户端自己选择不容的工具,其实与上面的实现方式没有区别,不过是把选择交通工具的判断移动到客户端代码。

public  Transportation{public void bike(){};public void bus(){};public void car(){};public void plane(){};public void train(){};}

     对于这种一个行为有多种实现方式的,策略模式就是用来解决上面代码封装带来的程序臃肿,代码混乱,以及违背开发-封闭原则。

使用策略模式实现代码如下:

交通工具抽象(相当于策略的抽象),用于定义交通工具共有的方法。声明了交通工具共有的移动的方法

public interface Transportation {public void move();}
每种交通工具具体的实现(相对于具体的策略)

public class Bike implements Transportation {@Overridepublic void move() {// TODO Auto-generated method stubSystem.out.println("move by bike");}}
public class Bus implements Transportation{@Overridepublic void move() {// TODO Auto-generated method stubSystem.out.println("move by bus");}}

接下来是上下文类,保存策略的引用

public class TransportContext {private Transportation transportation;public TransportContext(Transportation transportation) {this.transportation = transportation;}public void move(){transportation.move();}}

此时将不同的交通工具封装成单独的类,此时如果需要新增交通工具,只需加入新的交通工具的类,各种交通工具的代码也不会混杂在一起,此时修改Bike这种交通工具,绝对不会影响到Bus的实现。

当然上下文类还可以如下(将交通方式的选择转移到上下文类,并通过方式方法创建交通工具):

public class TransportContext {private Transportation transportation;private String transportPath = "com.xxx.transport";public TransportContext(String type) {String transportDetailPath = transportPath+type;try {Class<Transportation> transportationClazz = (Class<Transportation>) Class.forName(transportDetailPath);this.transportation = transportationClazz.newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void move(){transportation.move();}}

总结:

        策略模式:定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换。策略模式的功能是把具体的算法实现,从具体的业务处理里面独立出来,把它们实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。

        带来的好处就是,具体的策略都有单独的类,可扩展性更好,同时也让各策略的单元测试变得更加简单,各种策略都可以单独进行测试。

        缺点就是每种策略都是一个类,会定义出更多的类。
















策略模式在我的理解就是封装,将不同的策略(达到的目的是一样的,只是实现不同的方法)封装成独立的方法,使它们能够相互替换。