策略模式

初读《Head First》,自己的小记录。因为最近开始用c#,所以代码也用c#表示吧。(我知道写的很烂,但是我强迫自己要稍微写一下。。所以我才能真的认真看,并稍微有点思考的样子尴尬

首先是一个有关鸭子的系统。

Duck是鸭子的抽象类,MallardDuck,RedheadDuck是两种鸭子的具体类。他们都会quack和swim。

public abstract class Duck{
	public abstract void display ();

	public void quack(){
		Debug.Log ("quack");
	}
	public void swim(){
		Debug.Log ("swim");
	}
}

public class MallardDuck : Duck{
	public override void display(){
		Debug.Log("MallardDuck display");
	}
}

public class RedheadDuck : Duck{
	public override void display(){
		Debug.Log("RedheadDuck display");
	}
}



接着,鸭子里需要添加新成员橡皮鸭。

添加完橡皮鸭后,需要同display一样重载quack(因为叫声不一样

似乎这样就可以暂时解决了。


但是当我们想给鸭子添加fly行为时,又要对橡皮鸭的fly特殊处理(因为他没法飞

于是发现了, 鸭子的行为经常产生变化,且容易引起代码的修改。

所以,我们希望将变化的部分单独拆开来,这样需要改变时,我们可以很轻易的修改或者扩充。这样不用管稳定的部分,减少我们的工作量。


将fly和quack行为单独封装出来。

每个具体鸭子都拥有 fly和quack行为接口,并且具体鸭子类可以在运行时指定具体行为。

同时我们为Duck添加 setBehavior的功能,以便更灵活的动态改变行为。

public abstract class Duck{
	public QuackBehavior quackBehavior;
	public FlyBehavior flyBehavior;

	public void performQuack(){
		quackBehavior.quack ();
	}

	public void performFly(){
		flyBehavior.fly();
	}

	public void setFlyBehavior(FlyBehavior fb){
		flyBehavior = fb;
	}

	public void setQuackBehavior(QuackBehavior qb){
		quackBehavior = qb;
	}

	public abstract void display ();
	
}

public interface FlyBehavior{
	void fly();
}

public class FlyWithWings{
	public void fly(){
		Debug.Log ("FlyWithWingss");
	}
}

public class FlyNoWay{
	public void fly(){
		Debug.Log ("FlyNoWay");
	}
}

public interface QuackBehavior{
	void quack();
}

public class Quack : QuackBehavior{
	public void quack(){
		Debug.Log("gugu~~");
	}
}

public class Squack : QuackBehavior{
	public void quack(){
		Debug.Log("zhizhi");
	}
}

public class MuteQuack : QuackBehavior{
	public void quack(){
		Debug.Log("Mute Quack");
	}
}

public class MallardDuck : Duck{
	public MallardDuck(){
		flyBehavior = new FlyWithWings ();
		quackBehavior = new Quack ();
	}

	public override void display(){
		Debug.Log("MallardDuck display");
	}
}

public class RedheadDuck : Duck{
	public override void display(){
		Debug.Log("RedheadDuck display");
	}
}



设计原则:

1.封装变化

如果发现每次新的需求依赖。都会使某方面的代码发生改变,那么可以确定,这部分的代码需要被取出来,和其他稳定的代码有所区分。(例子中取出了鸭子的行为,并用 封装为行为接口)


2.多用组合(有一个),少用继承(是一个)

本例中,如果将鸭子的行为使用继承 赋予 鸭子具体类的话, 那么被继承的行为就固定下来了, 无法动态改变(可以看做是针对实现编程,失去灵活性)

而实际上,本例采用组合的方式,即鸭子类拥有 行为的接口实例, 并且鸭子拥有了“运行时动态改变行为”的可能性。

所以组合带给我们的好处应该是:灵活,动态改变


3.针对接口编程,而不是针对实现编程

针对实现编程: Dog d = new Dog;
针对接口/超类型编程: Animal animal = new Dog();

针对超类型编程,可以动态的改变行为(animal)


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





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值