设计模式初探之策略模式

         上周写了一篇静态工厂模式,现在讲一讲策略模式,同静态工厂模式一样,策略模式也是一种相对简单,容易理解的一种设计模式。首先看一下他的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 {

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("move by bike");
	}
}
public class Bus implements Transportation{

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.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 block
			e.printStackTrace();
		}
	}
	
	public void move(){
		transportation.move();
	}
}

总结:

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

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

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
















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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值