Java设计模式之策略模式

策略模式(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、通过条件语句在多个分支中选取一个

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式(Strategy Pattern)是Java设计模式中的一种行为型模式,它定义了一系列的算法,并将每个算法封装在独立的类中,使得它们可以互相替换。这样可以使得算法的变化独立于使用它们的客户端。 在策略模式中,有三个主要角色: 1. 环境类(Context):持有一个策略类的引用,用于调用具体的策略。 2. 抽象策略类(Strategy):定义了一个公共接口或抽象类,用于具体策略类的统一调用。 3. 具体策略类(Concrete Strategy):实现了抽象策略类定义的接口或抽象类,提供具体的算法实现。 使用策略模式可以实现算法的动态切换,增加新的算法也不会影响到已有的代码。例如,假设我们需要实现一个排序算法,可以定义一个抽象策略类 SortStrategy,然后具体的排序算法(如快速排序、归并排序等)分别实现 SortStrategy,并在环境类中持有 SortStrategy 的引用。这样,通过更换不同的 SortStrategy 对象,就可以在运行时选择不同的排序算法。 策略模式能够有效地解耦策略的定义和使用,提高代码的灵活性和可维护性。同时,它也符合面向对象设计原则中的"开闭原则"(对扩展开放,对修改关闭)和"单一职责原则"(一个类应该只有一个引起变化的原因)。 希望这个简要的介绍能够帮助到你对策略模式的理解。如果还有其他问题,可以继续提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值