设计模式(一):策略模式

一、『策略模式』定义

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

什么是算法族?可以把每套行为想象成一个算法族,即某个行为接口及它的所有实现类称为一个算法族。


二、场景

直接看定义是一脸懵,下面通过具体场景来一步步说明。

场景:描述不同品种的鸭子,如枫叶鸭、力加鸭、橡皮鸭、诱饵鸭等。

2.1 步骤一

对于不同品种的鸭子,我们需要用不同的类来描述。这时我们可以用标准的面向对象方式,即设计一个鸭子的超类来统一描述所有品种鸭子的共同属性和行为,再让各种鸭子继承自超类。另外,不同品种鸭对于同种行为有不同的表现(比如叫声),我们可以在超类中把该行为方法抽象化,让各种鸭子类自己实现该行为方法。

2.2 步骤二

现在有个问题,如果超类有【叫声】和【飞行】两种行为,但对于子类诱饵鸭既不会飞也不会叫,橡皮鸭不会飞但会叫,我们可能会想到覆盖方法但不实现具体功能。既然这样,我们不就可以把【叫声】和【飞行】设计成接口吗,当鸭子需要【叫声】和【飞行】就去实现这两个接口,而不需要这两个行为就不去实现接口。

设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

2.3 步骤三

现在又有个问题,因为是实现接口,而多种鸭子的【叫声】或者【飞行】可能相同,那么相应的实现也就相同了,我们会发现这部分的代码重复太多,并没有复用。这时我们可以针对接口编程,而不是针对实现编程。即对于【叫声】和【飞行】这两个接口,我们不是去实现它们,而是通过接口多态来使用。

设计原则:针对接口编程,而不是针对实现编程。

具体方法就是,对于【叫声】和【飞行】这两个接口我们是单独创建类来实现它们,而不是鸭子子类去实现。比如【吱吱叫】类或者【呱呱叫】类就是实现【叫声】接口,然后在鸭子超类中定义一个实例变量,即【叫声】这个接口变量,然后在子类中用多态 【叫声】 超类的接口变量 = new 【呱呱叫】 来使用。详细看Java代码:

// 飞行接口
interface FlyBehavior{
	void fly();
}

// 叫声接口
interface QuackBehavior{
	void quack();
}

// 实现飞行接口(会飞)
class FlyWithWings implements FlyBehavior{
	public void fly(){
		//鸭子飞行
	}
}

// 实现飞行接口(不会飞)
class FlyNoWay implements FlyBehavior{
	public void fly(){
		//鸭子不会飞行,什么也不做
	}
}

// 实现叫声接口(呱呱叫)
class Quack implements QuackBehavior{
	public void quack(){
		//鸭子呱呱叫
	}
}

// 实现叫声接口(吱吱叫)
class Squeak implements QuackBehavior{
	public void quack(){
		//鸭子吱吱叫
	}
}

// 实现叫声接口(不会叫)
class MuteQuack implements QuackBehavior{
	public void quack(){
		//鸭子不会叫,什么也不做
	}
}
/***************************我是分界线***************************/
// 鸭子超类
abstract class Duck{
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	
    public void performFly(){
		flyBehavior.fly();
	}
	public void performQuack(){
		quackBehavior.quack();
	}
}

//橡皮鸭(不会飞但会吱吱叫)
class RubberDuck extends Duck{
	public RubberDuck(){
		flyBehavior = new FlyNoWay();
		quackBehavior = new Squeak();
	}
}

//诱饵鸭(既不会飞也不会叫)
class DecoyDuck extends Duck{
	public DecoyDuck(){
		flyBehavior = new FlyNoWay();
		quackBehavior=new MuteQuack();
	}
}

参考

《HeadFirst设计模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值