设计模式之--策略模式

使用策略模式设计Duck行为
本文探讨了如何使用策略模式来设计Duck类及其多种行为,如swim(), fly(), display()和quack()。通过将可变行为(如fly()和quack())从Duck类中提取出来,形成单独的行为类,实现了行为的独立替换,提高了代码的灵活性和可维护性。" 118001325,5671957,Dubbo源码解析:FactoryBean与BeanFactory的理解与应用,"['Spring框架', 'Dubbo框架', '源码分析', '依赖注入', '工厂模式']

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

例:如何去设计一个Duck类,以及多样的继承与Duck类的子类呢?Duck有以下行为:swim(),fly(),display(),quack()。

1.首先思考一下,如果按照自己以往的习惯会怎么去设计呢?

定义一个Duck类,然后里面定义上述三个方法,所有继承与Duck类的子类都会包含这三个方法,我们可以去重写这三个方法,使子类可以拥有自己的变化。那么问题来了,假如,我有一只橡皮鸭,我不应该让它有飞的行为,我该怎么办呢?

2.利用重写呢?

那么是不是,每出现一个新的子类的时候,我们就要手动的对父类里的方法进行重写呢?这样的话,我们的代码一点复用性都不存在了,每次都要去重写一次。

3.利用接口怎么样?

好,我们把Duck的共同行为(不可变行为),与可改变行为分开,把fly()与quack()这两个方法做成接口,然后会飞的就去实现fly接口,会叫得就去实现quack接口。但是我们每次去继承某个接口的时候,我们就必须去手动实现接口里面的方法,还是要不断的写代码。

4.接下来应该怎么做

既然,我们都已经把Duck的可变与不可变行为分开了,那就分的彻底一些,把Fly与Quack专门做成两个行为类FlyBehavior与QuackBehavior,远离Duck类。不同的fly的方式都单独做成一个个类,这些类继承FlyBehavior父类。Quack也一样。例如,FlyWithWind继承与FlyBehavior。

5.如何把这些连接到一起?

我们在Duck类中,写上FlyBehavior flyBehavior和QuackBehavior quackBehavior两个字段,这两个字段。所有继承于Duck的子类都会有这两个字段,并在各自的构造方法中进行字段赋值,例如:flyBehavior = new FlyWithWing();   利用重写。这样,子类就相当于把飞行行为委托给了FlyWithWing类。

6.好处是什么?

只要我们写好了FlyBehavior与QuackBehavior以及他们的子类,我们就可以让他们帮助任何需要此行为的对象进行该行为。当对象以及代码非常多的时候,这样的模式使代码更容易拓展以及维护。

7.接口的隐式实现还可以进行优化:

把两个行为基类做成接口,然后Duck中两个字段定义成接口类型,然后通过    IFlyBehavior flyB = (IFlybehavior)new FlyWithWind()这样隐式实现接口中的方法。省去了不断的实例化类对象的过程。


下面为最终的模式写上这个示例的代码:


<p>/// <summary>
/// 策略模式Duck示例
/// </summary>
using System;
namespace StrategyPattern
{
	// Duck超类
	public abstract class Duck
	{
		// 两个可变行为的字段以及属性
		public IFlyBehvior flyBehavior;
		public IQuack quackBehavior;
		// 两个共有行为
		public void Swim()
		{
			Console.WriteLine ("I'm swimming");
		}
		public abstract void Display ();
	}
	// 继承与Duck的类 橡皮玩具鸭
	public class ToyDuck : Duck
	{
		#region implemented abstract members of Duck
		public override void Display ()
		{
			Console.WriteLine ("I'm ToyDuck");
		}
		#endregion
		// 构造器里对继承来的接口对象进行初始化。
		public ToyDuck()
		{
			flyBehavior = (IFlyBehvior)new FlyNoWay ();
			quackBehavior = (IQuack)new GuaGuaJiao ();
		}
	}

	// 两个行为接口,以及继承这些接口的行为类
	public interface IFlyBehvior
	{
		void Fly ();
	}
	public interface IQuack
	{
		void Quack ();
	}
	public class FlyWithWind : IFlyBehvior
	{
		#region IFlyBehvior implementation
		void IFlyBehvior.Fly ()
		{
			Console.WriteLine ("I'm fly With Wind");
		}
		#endregion
	}
	public class FlyNoWay : IFlyBehvior
	{
		#region IFlyBehvior implementation
		void IFlyBehvior.Fly ()
		{
			Console.WriteLine ("I can't fly");
		}
		#endregion
	}
	public class GuaGuaJiao : IQuack
	{
		#region IQuack implementation
		void IQuack.Quack ()
		{
			Console.WriteLine ("gua gua");
		}
		#endregion
	}
	public class NoQuack : IQuack
	{
		#region IQuack implementation
		void IQuack.Quack ()
		{
			Console.WriteLine ("I can't quack");
		}
		#endregion
	}

	class MainClass
	{
		public static void Main (string[] args)
		{
			// 调用橡皮玩具鸭的fly方法与quack方法
			ToyDuck td = new ToyDuck ();
			td.flyBehavior.Fly ();
			td.quackBehavior.Quack ();
		}
	}
}<span style="font-size:14px;">
</span></p>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值