您的位置:首页 > 职场人生

码农小汪-设计模式之-命令模式

2016-04-16 19:36 417 查看
大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了。想到这些特殊的例子感觉就是特别爽。

烤羊肉串带来的思考!

路边摊羊肉串:

老板,我这里排的比较先啊,我最先给钱。老板这个没有熟啊。我的是 辣的啊!老板没有放盐啊!场面混乱,已经分不清谁是谁的啊,人太多了。烤肉的质量也受到了影响,心情不好也就不好啊。烤肉的人心情受到了顾客的影响。

店面的烤肉

服务员,给我来两串羊肉串,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模式解耦,请求者无需知道接受者任何接口。

缺点: 造成出现过多的具体命令类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: