重构之职责链模式

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

应用场景:
商店老板向一家三口推销冰激凌,
小孩可以决定是否购买价格为10,数量为1的冰激凌,
爸爸可以决定是否购买价格区间为10~100,数量区间为大于1的冰激凌,
妈妈可以决定是否购买价格区间为大于100,数量区间为大于1的冰激凌。
故而进行如下代码的编写

首先,来看一下没有用职责链时,我们的代码是这样的:
//冰激凌
public class Ice_Cream
{
	//冰激凌的价格
	private int price;
	public int Price
	{
		get {return price;}
		set {price=value;}
	}
	//冰激凌的数量
	private int num;
	public int Num
	{
		get {return num;}
		set {num=value;}
	}
}
//决定者
public class people
{
//获得结果
	public void GetResult(string Status,Ice_Cream ice)
	{
		if (Status=="Kid")
		{
			if(ice.Price<=10 && ice.Num==1)
			{
				Console.WriteLine("孩子可以买");
			}
			else
			{
				Console.WriteLine("孩子买不了,让孩儿的爸爸买");
			}
		}
		if (Status=="Dad")
		{
			if (ice.Price>=10 && ice.Price<=100 && ice.Num>1)
			{
				Console.WriteLine("爸爸可以买");
			}
			else
			{
				Console.WriteLine("爸爸买不了,让孩儿的妈妈买");
			}
		}
		if (Status=="Mom")
		{
			if (ice.Price>100 && ice.Num>1)
			{
				Console.WriteLine("妈妈可以买");
			}
		}
	}
}
public static void Main(string[] args)
{
	Ice_Cream ice=new Ice_cream();
	ice.Price="50";
	ice.Num="2";
	People kid=new People();
	People dad=new People();
	People mom=new People();
	kid.GetResult("kid",ice);
	dad.GetResult("Dad",ice);
	mom.GetResult("Mom",ice);
	Console.Read();
}
从上面的代码中,我们可以看到,要想确定冰激凌价格和数量由谁可以决定是否购买,必须要不断进行if判断,在People类中,if分支太长,代码设计不佳,此外三个决策者之间缺乏关联,需要多次调用GetResult方法进行if判断,效率低下。
因此,我们对上述代码进行重构,利用职责链模式,将People类中的三个决策者关联起来,进行层层递进的查找。

在这里插入图片描述

//定义一个抽象类决策者
public abstract class People
{
	protected People successor;
	//设置继承者
	public void Setsuccessor(People successor)
	{
		this.successor=successor;
	}
	//定义一个获取结果的抽象方法 
	public abstract void GetResult(Ice_Cream ice);
}
public class Kid:People
{
	//重写抽象方法GetResult
	public override void GetResult(Ice_Cream ice)
	{
		if(ice.Price<=10 && ice.Num==1)
		{
			Console.WriteLine("孩子可以买");
		}
		else if (successor != null)
		{
			//转到下一个更高的级别
			successor.GetResult(ice);
		}
	}
}
public class Dad:People
{
	public override void GetResult(Ice_Cream ice)
	{
		if (ice.Price>=10 && ice.Price<=100 && ice.Num>1)
		{
			Console.WriteLine("爸爸可以买");
		}
		else if (successor != null)
		{
			successor.GetResult(ice);
		}
	}
}
public class Mom:People
{
	public override void GetResult(Ice_Cream ice)
	{
		if (ice.Price>100 && ice.Num>1)
		{
			Console.WriteLine("妈妈可以买");
		}
		else if (successor != null)
		{
			successor.GetResult(ice);
		}
	}
}
public static void Main(string[] args)
{
	/*运用多态,将子类对象赋给父类变量
	*在编译过程中,kid,dad,mom作为父类变量身份存在
	*在运行过程中,kid,dad,mom调用子类自己的方法来实现
	*/
	People kid=new Kid();
	People dad=new Dad();
	People mom=new Mom();
	//设置下一个更高级别,孩子的下一位是父亲,父亲的下一位是母亲
	kid.SetSuccessor(dad);
	dad.SetSuccessor(mom);
	Ice_Cream ice=new Ice_Cream();
	ice.Price="50";
	ice.Num="2";
	//从最小一级开始进行调用
	kid.GetResult(ice);
	Console.Read();
}

通过上面两个例子的对比,是不是对职责链有了一个简单的认识呢?

在之后我们的重构中,如果存在上下级关系的分层次的判断,可以尝试利用职责链设计模式去实现,可以使代码封装的更好,且有效的降低耦合度。

猜你喜欢

转载自blog.csdn.net/YaraRen/article/details/106682630