标签:
大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了。想到这些特殊的例子感觉就是特别爽。
烤羊肉串带来的思考!
路边摊羊肉串:
老板,我这里排的比较先啊,我最先给钱。老板这个没有熟啊。我的是 辣的啊!老板没有放盐啊!场面混乱,已经分不清谁是谁的啊,人太多了。烤肉的质量也受到了影响,心情不好也就不好啊。烤肉的人心情受到了顾客的影响。
店面的烤肉
服务员,给我来两串羊肉串,2鸡翅,啤酒两瓶。
鸡翅没得啦,点别的吧,肉精吧。辣一点。
两者的比较啊:
路边的生意不稳定,往往就是那几个时间,客源不固定的,人多混乱,所以生意也是不稳定的。烤肉的时候谁都想最先吃到啊,烤肉老板一个人,所以忙的混乱啊。所有的人都没有事情,都盯着这里看,烤肉多那一串,考的好,大家都是比较的清楚的。
这里出现了什么关系了呢?
紧耦合
客户和肉串老板的紧耦合,所以容易出错和乱起来,也容易挑剔。这里就是行为的请求者和行为的实现者的紧耦合。我们需要记录哪几个人的羊肉串,有没有特殊的要求(辣不辣),付钱了没有,谁先谁后啊。这个都是请求做什么哦。对于请求的做出记录哦,也就是日志。
如果有人要求撤出请求不要了,或者有人要求重新烤过,这其实就是什么呢?
撤销和重做吧
所以啊,所有的请求排队或者记录日志,一节支持可以撤销的操作等行为时。行为的请求者和实现者之间的紧耦合是不是太合适的。
我们再说说烤肉店吧!
我们不认识烤肉的师傅,见都没有见到。我们只需要给接待的服务员说就好了。她给我们记录,然后将订单交给师傅去做。都有订单,必有先后顺序。不会乱,不会遗忘。
服务员,肉串太多了,给我少一串好?服务员在订单上画了一笔。搞定,然后通知师傅。让服务员解耦我们的客户与烤肉者之间的耦合这的不错哦
编程融入生活!
我们的抽象命令
//抽象命令
public abstract class Command
{
protected Barbecuer receiver;//烤肉串的执行者
public Command(Barbecuer receiver)
{
this.receiver = receiver;
}
//执行命令
abstract public void ExcuteCommand();
}
这个命令的实现类,考啥子东西呢?考火腿,肌肉,还是其他的一些东西呢?
//烤羊肉串命令
class BakeMuttonCommand : Command
{
public BakeMuttonCommand(Barbecuer receiver)
: base(receiver)
{ }
public override void ExcuteCommand()
{
receiver.BakeMutton();
}
}
//烤鸡翅命令
class BakeChickenWingCommand : Command
{
public BakeChickenWingCommand(Barbecuer receiver)
: base(receiver)
{ }
public override void ExcuteCommand()
{
receiver.BakeChickenWing();
}
}
我们烤肉的人在干啥呢?
//烤肉串者
public class Barbecuer
{
public void BakeMutton()
{
Console.WriteLine("烤羊肉串!");
}
public void BakeChickenWing()
{
Console.WriteLine("烤鸡翅!");
}
}
还有个重要的人物就是我们的服务员啊,这个解耦的重要的工具。服务员下订单就是让我们的烤肉啊,还是其他的一些东西执行起来,最后的时候才可以去执行的。
//服务员
public class Waiter
{
private Command command;
//设置订单
public void SetOrder(Command command)
{
this.command = command;
}
//通知执行
public void Notify()
{
command.ExcuteCommand();
}
}
最后看我们怎么去执行呢?
//开店前的准备
Barbecuer boy = new Barbecuer(); 烤肉的人
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 创建一个烤那个啥的,谁去烤呢?就是烤肉的
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
Waiter girl = new Waiter();
//开门营业
girl.SetOrder(bakeMuttonCommand1);//下个订单,让我们的师傅去执行
girl.Notify();
girl.SetOrder(bakeMuttonCommand2);
girl.Notify();
girl.SetOrder(bakeChickenWingCommand1);
girl.Notify();
这个程序肯定是还有问题的吧,真实的情况怎么可以这样的呢?每次只能点一个菜呢,通知一次。
第二嘛,我们不知道厨房的东西是否还有没得?我们应该检查一下涩,让我们的服务员
第三,我们的客户点了哪些菜我们是应该做记录的,以后好收费,还有可能客服中途取消之内的东西。
服务员,有个list的订单
public class Waiter
{
private IList<Command> orders = new List<Command>();
//设置订单
public void SetOrder(Command command)
{
if (command.ToString() == "命令模式.BakeChickenWingCommand")
{
Console.WriteLine("服务员:鸡翅没有了,请点别的烧烤。");
}
else
{
orders.Add(command);
Console.WriteLine("增加订单:" + command.ToString() + " 时间:" + DateTime.Now.ToString());
}
}
//取消订单
public void CancelOrder(Command command)
{
orders.Remove(command);
Console.WriteLine("取消订单:" + command.ToString() + " 时间:" + DateTime.Now.ToString());
}
//通知全部执行
public void Notify()
{
foreach (Command cmd in orders)
{
cmd.ExcuteCommand();
}
}
}
执行的过程和我们的刚才是一样的哦,所以不要担心的。
命令模式:Command 将我们的一个请求封装成为一个对象,从而使你可用不同的请求对客服进行参数化,对请求排队或记录日志,以及支持可以撤销的操作。
我们看看我们的图片
Command命令设计模式中5个角色:
(1).客户角色:创建了一个具体命令对象并确定其接收者。
Barbecuer boy = new Barbecuer(); 烤肉的人
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 命令,烤肉的人是接收者
(2).命令角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个java接口或java抽象类实现。
这个就是我们上面的Command,我们的服务员依赖于他。必须有命令服务员才去通知我们的厨房哦
(3).具体命令角色:定义一个接受者和行为之间的弱耦合;实现execute方法,负责调用接收者的相应操作。execute方法通常叫做 执行方法。
这里好理解吧,我们这个方法依赖于我们的具体的执行者,烤肉的人。烤肉的人里面的哪种方法呢?我们烤的是啥子?
(4).请求者(Invoke)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
这个就是相当于我们的服务员哦,对吧!
(5).接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
我们每一个命令的具体的执行者就是他,他就是烤肉的老板
命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。每一个命令都是一个操作,命令请求发出请求要求执行一个操作;命令接受方收到请求,并执行操作。命令模式允许命令请求方和命令接收方独立开来,使得命令请求方不必 知道命令接收方的接口,更不必知道请求是怎么被接收,以及操作是否被执行,何时被执行,以及是怎么被执行的。
服务员
//请求者角色
class Invoker{
private Command command;
public Invoker(Command command){
this.command = command;
}
public void action(){
command.execute();
}
}
烤肉的
//接收者
class Receiver{
//行动方法
public void action(){
System.out.println("Action has been taken.");
}
}
服务员依赖于Command ,Command 依赖于我们的接受者,烤肉的那个人。这样就间接的传达话语!
//抽象命令角色
interface Command{
void execute();
}
//具体命令类
class ConcreteCommand implements Command{
private Receiver receiver;
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
public void execute(){
receiver.action();
}
}
客服端怎么样呢?
//客户端
public class Client{
public static void main(String[] args){
//客户端创建命令接受者
Receiver receiver = new Receiver();
//客户端创建具体命令,并指定命令接受者
Command command = new ConcreteCommand(receiver);
//客户端创建请求者,并给请求者指定具体命令
Invoker invoker = new Invoker(command);
//命令请求者发出命令请求
invoker.action();
}
}
Command命令设计模式的优缺点:
优点: 解耦了命令请求者和接受者之间联系。请求者调用一个命令,接受者接受请求并执行相应的动作,因为使用Command模式解耦,请求者无需知道接受者任何接口。
缺点: 造成出现过多的具体命令类。
标签:
原文地址:http://blog.csdn.net/u012881904/article/details/51155874