java 开发模式之一 : 策略模式

原理或定義

定义一组算法,将每个算法都封装起来,并且使他们之间可以互换

结构

封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。

 

抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。

 

具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。

類圖


案例和代码

本模式以模拟鸭子项目来做示例

OO思维里的继承方式解决方案是:

public abstract class Duck {
		...;
		public void Fly() {
		System.out.println("~~im fly~~");
	}	
}
问题来了,这个Fly让所有子类都会飞了,这是不科学的。
继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。影响会有溢出效应。


继续尝试用OO原理来解决,覆盖

public class GreenHeadDuck extends Duck {
...;
public void Fly() {
		System.out.println("~~no fly~~");
	}	
}

又有新需求,石头鸭子,填坑:

public class StoneDuck extends Duck {
....	}
超类挖的一个坑,每个子类都要来填,增加工作量,复杂度O(N^2)。不是好的设计方式

需要新的设计方式,应对项目的扩展性,降低复杂度:
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行...


使用策略模式:

鸭子基类

public abstract class Duck {

	FlyBehavior mFlyBehavior;
	public Duck() {
	}
	public void Fly() {
		mFlyBehavior.fly();
	}
	public abstract void display();
	public void SetQuackBehavoir(QuackBehavior qb) {
		mQuackBehavior = qb;
	}
	public void SetFlyBehavoir(FlyBehavior fb) {
		mFlyBehavior = fb;
	}
	public void swim() {
		System.out.println("~~im swim~~");
	}
}


鸭子子类

public class GreenHeadDuck extends Duck {

	public GreenHeadDuck() {
		mFlyBehavior = new GoodFlyBehavior();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("**GreenHead**");
	}

}


public class RedHeadDuck extends Duck {

	public RedHeadDuck() {
		mFlyBehavior = new BadFlyBehavior();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("**RedHead**");
	}

}

行为接口(抽象策略

public interface FlyBehavior {
	void fly();
}


行为类(具体策略

public class	BadFlyBehavior implements FlyBehavior
{
	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("--BadFly--");
	}
}

public class	GoodFlyBehavior implements FlyBehavior
{
	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("--GoodFly--");
	}
}

测试方法

public class StimulateDuck {

	public static void main(String[] args) {

		Duck mGreenHeadDuck = new GreenHeadDuck();
		Duck mRedHeadDuck = new RedHeadDuck();

		mGreenHeadDuck.display();
		mGreenHeadDuck.Fly();
		mGreenHeadDuck.swim();

		mRedHeadDuck.display();
		mRedHeadDuck.Fly();
		mRedHeadDuck.swim();
		mRedHeadDuck.display();
		mRedHeadDuck.SetFlyBehavoir(new NoFlyBehavior());
		mRedHeadDuck.Fly();
	}

}

好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没有挖坑


使用場景

1几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。

2有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用

優缺點

主要优点有

策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。

易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。

缺点主要有

维护各个策略类会给开发带来额外开销

必须对客户端(调用者)暴露所有的策略类,因为使用哪种策略是由客户端来决定的,因此,客户端应该知道有什么策略,并且了解各种策略之间的区别

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值