Java设计模式之策略模式

策略模式:对于父类中变化行为的部分,分别对其封装行为接口,实现行为族(算法族),
在子类里具体设定行为对象(也就是new 一个对象,注意到的是父类只是声明对象).


原则是:分离变换部分,封装接口,基于接口编程各种功能.此模式让行为算法的变换独立
于算法的使用者!


使用策略模式需要注意到的几点:


1.分析项目中变化部分与不变化的部分


2.多用组合少用继承;用行为类组合(也就是行为族),而不是行为的继承,这样更具有弹性


3.设计模式是没有响应的库直接提供你使用的!注意到的是:有些库或者框架本身就用某种设计模式设计的






下面我们就以一个模拟鸭子的游戏来说明策略模式:(重要代码都给了注释):


父类(超类):
Duck.java:

package com.java.hexter.stimulateduck.duck;

import com.java.hexter.stimulateduck.flybehavior.FlyBehavior;
import com.java.hexter.stimulateduck.quackbehavior.QuackBehavior;
///超类 也就是父类
public abstract class Duck {
    ///通过策略模式:超类里面放的是行为的对象(这里是mFlyBehavior和mQuackBehavior)
	FlyBehavior mFlyBehavior;
	QuackBehavior mQuackBehavior;

	public Duck() {///构造函数

	}

	public void Fly() {///在超类中不会写集具体的代码实现
		mFlyBehavior.fly();
	}

	public void Quack() {
		mQuackBehavior.quack();
	}

	public abstract void display();
    
	///通过set方法可以改变对象的属性,动态的变化,而不是只是简单的通过构造函数初始化一下(一成不变)
	public void SetQuackBehavoir(QuackBehavior qb) {
		mQuackBehavior = qb;
	}

	public void SetFlyBehavoir(FlyBehavior fb) {
		mFlyBehavior = fb;
	}

	public void swim() {///共同的行为就可以放到超类中
		System.out.println("~~im swim~~");
	}
}


接下来就是Duck的两个子类:GreenHeadDuck.java和RedHeadDuck.java


GreenHeadDuck.java:


package com.java.hexter.stimulateduck.duck;

import com.java.hexter.stimulateduck.flybehavior.GoodFlyBehavior;
import com.java.hexter.stimulateduck.quackbehavior.GaGaQuackBehavior;

public class GreenHeadDuck extends Duck {
    ///超类中访接口对象 子类中具体设定行为对象(也就是new一个对象)
	public GreenHeadDuck() {
		mFlyBehavior = new GoodFlyBehavior();
		mQuackBehavior = new GaGaQuackBehavior();
	}
    ///我们这里只对行为和飞行做处理, display就不处理了
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("**GreenHead**");
	}

}

RedHeadDuck.java:


package com.java.hexter.stimulateduck.duck;

import com.java.hexter.stimulateduck.flybehavior.BadFlyBehavior;

import com.java.hexter.stimulateduck.quackbehavior.GeGeQuackBehavior;

public class RedHeadDuck extends Duck {

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

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

}

然后就是封装行为的接口(FlyBehavior.java和QuackBehavior.java)

FlyBehavior.java:

package com.java.hexter.stimulateduck.flybehavior;

public interface FlyBehavior {
	///注意到的是:我们把方法封装成了一个行为接口,多个行为接口就形成了一个行为族(算法族)
	///一般的思路都是:子类继续父类,没有实现的方法在子类中实现,这里是把子类中实现的代码
	///提取出来 形成一个行为接口 然后再单独安排对应的实现类去实现,这样的好处就是不要重复
	///的写相同的代码,只需要调用行为接口的对象即可,这就是策略模式的精华(需要注意到的是:
	///策略模式只针对行为中变化的部分,一成不变,换句话说就是父类的某一特点子类都有且一样,不变的
	///部分直接写在父类里面就Ok了)
	
	void fly();
}


QuackBehavior.java:

package com.java.hexter.stimulateduck.quackbehavior;

public	interface QuackBehavior {
	void quack();
};


然后就是这些行为接口的实现类(这里只各举一种):

GoodFlyBehavoior.java:

package com.java.hexter.stimulateduck.flybehavior;



public class	GoodFlyBehavior implements FlyBehavior
{

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



GaGaQuackBehavoir.java:

package com.java.hexter.stimulateduck.quackbehavior;



public	class GaGaQuackBehavior implements QuackBehavior
{

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


接下来就是主函数的调用了:

创建一个名为StimulateDuck.java:

package com.java.hexter.stimulateduck;

import com.java.hexter.stimulateduck.duck.Duck;
import com.java.hexter.stimulateduck.duck.GreenHeadDuck;
import com.java.hexter.stimulateduck.duck.RedHeadDuck;
import com.java.hexter.stimulateduck.flybehavior.NoFlyBehavior;
import com.java.hexter.stimulateduck.quackbehavior.NoQuackBehavior;


public class StimulateDuck {

	public static void main(String[] args) {
        ///这里之所以用了Duck 而不用对应自己的类名 原因:多态性,易于程序的扩展
		Duck mGreenHeadDuck = new GreenHeadDuck();
		Duck mRedHeadDuck = new RedHeadDuck();

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

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

}
输出的结果为:
**GreenHead**
--GoodFly--
__GaGa__
~~im swim~~
**RedHead**
--BadFly--
__GeGe__
~~im swim~~
**RedHead**
--NoFly--
__NoQuack__


需要注意到的是:这里的BadFly GeGe  NoFly NoQuack我没有一一写出来,道理和GoodFly等等一样




最后总结一下:


这个模拟鸭子的项目:通过策略模式把变化的部分封装成行为的接口族(族:代表有很多接口),然后单独开对应行为接口族的实现类,那么调用的时候只需要调用接口族的类名即可,这样就不必要在子类中写重复的代码了,提高了代码的复用性和扩展性!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弗兰随风小欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值