Java设计模式之策略模式

原创 2017年05月09日 22:32:22

策略模式(strategy pattern):定义了算法族,分别封闭起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.

策略模式的结构

  策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。


这个模式涉及到三个角色:

环境(Context)角色:持有一个Strategy的引用。

抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。


接下来用形象生动的案例让大家明白。现在公司里面已经开发了一款应用,主要是展示大自然中的狗的应用,在市场中得到了很大的反响,获得了很大的成功。


狗的抽象类:

/**
 * 超类,所有的狗都要继承此类
 * @author JUN
 *
 */
public abstract class Dog {
	//发出叫声
	public void quack(){
		System.out.println("旺旺旺");
	}
	
	//显示狗的外观
	public abstract void display();
	
}

描述二哈类:

public class FoolishDog extends Dog {
	public FoolishDog() {
		super();
	}

	@Override
	public void display() {
		System.out.println("我是二哈,我老是做一些奇怪的表情!");
	}
	
	
	public void quack(){
		System.out.println("啊嗚嗚嗚~~~");
	}
	

}

描述柴犬类:

public class YellowDog extends Dog {
	public YellowDog() {
		super();
	}
	@Override
	public void display() {
		System.out.println("我是柴犬,我全身黃黃的");
	}

}


但是为了应对激烈的竞争,公司需要变革才能保持已有的优势。这是就需要对产品新增一些新的功能。比如给狗增加飞行、上天的能力。


那么有什么方法可以给应用很灵活的增加这些功能呢?

继承:在父类中提供实现方法,子类通过继承获得父类中的飞行或者上天的行为。
虽然简单易用(粗暴丑陋),在已有应用中课快速添加飞行的能力。但是不具有灵活性,对未来变更支持差。
需要在子类中覆写飞行方法已提供新的飞行行为。这很容易造成错误。

抽象方法:在父类中提供抽象方法,强迫子类实现自己的飞行行为。
虽然足够灵活。但是很麻烦累人,每个子类都要实现一遍代码,即使相同的行为也不例外。代码重复,没有复用代码。


那么还有什么更好的办法吗?

当我们Java学习到一定程度就会明白:复合优于继承,多用组合,少用继承。

那么该如何使用策略模式呢?接下来就进行代码操作:

添加一个策略接口:

/**
 * 策略接口
 * 
 * @author JUN
 * 
 */
public interface FlyingStrategy {
	void performFly();
}

在狗的抽象类中增加红框中的代码:


上述的柴犬和二哈都是自然界中真实的狗,接下来如果我们要给狗增加不能飞行、飞行和上天的行为,那么我们现在来添加一下具体的策略角色,具体策略角色需要实现我们的策略接口

不能飞行的功能:

public class FlyNoWay implements FlyingStrategy {

	@Override
	public void performFly() {
		System.out.println("我是走地狗!");
	}

}

可以飞行的功能:

public class FlyWithWin implements FlyingStrategy {

	@Override
	public void performFly() {
		System.out.println("我有翅膀,我會飛!");
	}

}

可以上太空的功能:

public class FlyWithRocket implements FlyingStrategy {

	@Override
	public void performFly() {
		System.out.println("我坐太空火箭!");
	}

}

这时我们策略模式中的角色都有了:


接下来我们需要给柴犬和二哈添加一个相对应的行为,由于它们都是自然界中真实的狗都不能飞行,所以我们只需在构造方法中加一行代码就可以:

二哈类的变化:


柴犬类的变化:


好了,以上都准备完毕,接下来我们来感受一下策略模式的好处。公司下一阶段的项目将是开发会飞行的狗,我们只需这样添加一个类:

天狗类:

public class FlyDog extends Dog {
	public FlyDog() {
		super();
		super.setFlyingStrategy(new FlyWithWin());
	}

	@Override
	public void display() {
		System.out.println("我是天狗,天狗望月!");
	}

}

好了天狗类的产品已经完成,再下一阶段公司打算让狗上太空,那么我们依旧简单的这样添加一个类:

太空狗类:

public class SpaceDog extends Dog {

	public SpaceDog() {
		super();
		super.setFlyingStrategy(new FlyWithRocket());
	}

	@Override
	public void display() {
		System.out.println("我是太空狗,太空狗登月!");
	}

	public void quack() {
		System.out.println("我通过无线电与你通信");
	}

}

接下来我们写一个狗的测试类:

public class DogTest {
	public static void main(String[] args) {
		System.out.println("测试开始");
		System.out.println("*******");
		Dog dog = null;
		
		dog = new YellowDog();  //柴犬
//		dog = new FoolishDog();  //二哈
//		dog = new FlyDog();     //天狗
//		dog = new SpaceDog();   //太空狗

		
		dog.display();
		dog.quack();
		dog.fly();
		
		System.out.println("***********");
		System.out.println("测试完成");
		
	}
}

逐一运行,柴犬和二哈的运行结果:

     

天狗和太空狗的运行结果:

    


现在有感觉到策略模式的好处了吧!这里建议我们多去代码实现一下,体验一下才能牢记。
最后我们总结一下:
策略模式的优点:
1、使用了组合,使架构更加灵活
2、富有弹性,可以较好的应对变化(开闭原则)
3、更好的代码复用(相对于继承)
4、消除大量的条件语句

缺点
1、客户代码需要了解每个策略实现的细节
2、增加了对象的数目

策略模式的使用场景:
1、许多相关的类仅仅是行为差异
2、运行是选取不同的算法变体
3、通过条件语句在多个分支中选取一个

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java 设计模式 策略模式

  • 2014年04月19日 17:16
  • 11KB
  • 下载

Java设计模式-策略模式

  • 2015年01月25日 01:29
  • 7KB
  • 下载

(十五)Java设计模式之策略模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述策略(Strategy)模式的:  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互...
  • zbdxcyg
  • zbdxcyg
  • 2017年10月23日 11:37
  • 54

JAVA设计模式demo之策略模式

  • 2017年11月04日 18:32
  • 7KB
  • 下载

[设计模式]-策略模式-JAVA语言

简单工厂模式只能决定实例化的对象,如果将来功能变多类也会随之变多.然而面向对象并不是类越多越好,类的划分是为了封装,而分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类由此引申出了策略模式,刚...
  • StanHYJ
  • StanHYJ
  • 2016年11月23日 22:11
  • 62

Java设计模式之策略模式

  • 2016年10月29日 21:34
  • 16KB
  • 下载

Java设计模式:策略模式 Strategy

1.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。 2. public inte...
  • sidihuo
  • sidihuo
  • 2016年02月26日 18:13
  • 226

java设计模式之策略模式

  • 2013年10月25日 20:43
  • 10KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java设计模式之策略模式
举报原因:
原因补充:

(最多只允许输入30个字)