日常生活中,我们去饭店吃饭,其实就是一种设计模式的体现:命令模式。
命令模式主要是把请求封装起来,把命令的请求者和命令的执行者解耦。在直白点,就是命令的请求者不知道具体的执行细节,而命令的执行者不知道谁在请求命令。他们之间唯一的联系就是命令对象本身了。
再说回到我们的饭店。我们顾客一般到了饭店,就是把点的订单交给服务员。服务员再把顾客的订单交给厨师,厨师做对应的菜。在这个过程中,服务员就是我们命令模式中的请求者了,订单是顾客交给服务员(请求者)的,请求者并不关心也不知道具体内容。他会直接把订单交给厨师(执行者)。而厨师(执行者)不知道也不关心具体是哪个服务员交给他的订单,他只要接到订单并开始做对应的菜(执行)就好了。
下面看代码:
//每个菜就是一个命令,并且含有执行方法
public interface MakeMeal
{
void Make();
}
public class Meal1
{
public void Make()
{
Console.WriteLine("Meal1");
}
}
public class Meal2
{
public void Make()
{
Console.WriteLine("Meal2");
}
}
public class MakeMeal1 : MakeMeal
{
Meal1 meal1;
public MakeMeal1(Meal1 meal1)
{
this.meal1 = meal1;
}
public void Make()
{
meal1.Make();
}
}
public class MakeMeal2 : MakeMeal
{
Meal2 meal2;
public MakeMeal2(Meal2 meal2)
{
this.meal2 = meal2;
}
public void Make()
{
meal2.Make();
}
}
public class Waiter
{
private List<MakeMeal> mealList;
//服务员从顾客那得到菜单列表
public Waiter(List<MakeMeal> mealList)
{
this.mealList = mealList;
}
//服务员传递菜单列表
public List<MakeMeal> TakeList()
{
return mealList;
}
}
public class Chef
{
private List<MakeMeal> mealList;
//厨师得到菜单列表
public Chef(List<MakeMeal> mealList)
{
this.mealList = mealList;
}
//厨师遍历菜单列表里的所有菜,调用执行
public void Make()
{
foreach(MakeMeal makeMeal in mealList)
{
makeMeal.Make();
}
}
}
class Program
{
static void Main(string[] args)
{
//我们就是顾客,我们选好几个菜后,放入菜单列表
List<MakeMeal> mealList = new List<MakeMeal>();
Meal1 meal1 = new Meal1();
Meal2 meal2 = new Meal2();
MakeMeal1 makeMeal1 = new MakeMeal1(meal1);
MakeMeal2 makeMeal2 = new MakeMeal2(meal2);
mealList.Add(makeMeal1);
mealList.Add(makeMeal2);
//我们叫来一个服务员,把菜单交给他
Waiter waiter = new Waiter(mealList);
//服务员把菜单交给厨师,在这个过程中,服务员不知道菜单的细节,他只要把菜单直接给厨师就好了
Chef chef = new Chef(waiter.TakeList());
//厨师拿到菜单后,开始做菜
chef.Make();
}
}
就像我们上面所说的,服务员(请求者)在接到菜单,把菜单传给厨师的过程中,不知道到菜单的细节。
这样,无论我们怎么修改菜单的细节,请求者都不关心,他只负责传递就好了。而厨师呢,也不用管你都点的哪些东西,只要把菜单上有的菜全部做一遍就好了。
PS:其实最后实现时,还是依赖了具体实现而不是依赖接口。(厨师接收菜单时不应该知道具体是谁给他的菜单,只知道是Waiter给的就好(抽象))。