package commandMode;

/*
 * 这次来个点菜
 */
public class Commonly {
	public static void main(String[] args) {
		Cook cook  = new  Cook();
		cook.gbjd();
		cook.gbjd();
		cook.gbjd();
		cook.gbjd();
		cook.gbjd();
		cook.hsr();
		cook.hsr();
		cook.hsr();
		cook.hsr();
		cook.gbjd();
		//这里请求多了就容易乱   不管是做宫保鸡丁还是红烧肉 都是厨师的行为 也就是厨师的方法  
		//具体怎么做都是由方法内部实现的 我们不用去管他  但是对于服务员来说 他就只需要根据客户的需要告诉厨师做什么
		//
		//优化 Commonly2.java
	}
}

class Cook{
	public void gbjd(){
		System.out.println("宫保鸡丁");
	}
	public void hsr(){
		System.out.println("红烧肉");
	}
}
package commandMode;

/*
 * 这次来个点菜
 */
public class Commonly2 {
	public static void main(String[] args) {
		 	//上班之前
		Cook2 cook = new Cook2();
		Command gbjdcommand  = new gbjdCom(cook);
		Command gbjdcommand2 = new gbjdCom(cook);
		Command hsrcommand = new hsrCom(cook);
		Waiter waiter = new Waiter();
		
		//来客人了
		waiter.setOrder(gbjdcommand);
		waiter.Notify();
		waiter.setOrder(gbjdcommand2);
		waiter.Notify();
		waiter.setOrder(hsrcommand);
		waiter.Notify();
		
		//有待改进
		//1.这里是点一个菜 服务员就通知厨师做一个 不科学 应该是全点完了之后再做
		//2.如果没有鸡丁了 应该是服务员通知客户  不应该是客户自己知道么有了  客户咋能知道你家没有鸡丁了
		//3.用户点了那些东西是要记录日志的  是需要收费的   或者以后查看什么的
		//4.用户点多了   是可以取消的
		//改进 看CommandMode.java
	}
}

/*
 * 命令抽象
 */
abstract class Command{
	protected Cook2 cook;
	public Command(){
	}
	public Command(Cook2 cook){
		this.cook = cook;
	}
   public abstract void ExcuCommand();
}

/*
 * 宫保鸡丁
 */
class gbjdCom extends Command{
	public gbjdCom(Cook2 cook){
		this.cook = cook;
	}
	public void ExcuCommand() {
		cook.gbjd();
	}
}

/*
 * 红烧肉
 */
class hsrCom extends Command{
	public hsrCom(Cook2 cook){
		this.cook = cook;
	}
	public void ExcuCommand() {
		cook.hsr();
	}
}

/*
 * 服务员
 */
class Waiter{
	private  Command command;
	public void setOrder(Command command){
		this.command = command;
	}
	//通知厨师做菜
	public void Notify(){
		command.ExcuCommand();
	}
}












/*
 * 厨师
 */
class Cook2{
	public void gbjd(){
		System.out.println("宫保鸡丁");
	}
	public void hsr(){
		System.out.println("红烧肉");
	}
}






package commandMode;

import java.util.ArrayList;
import java.util.List;

/*
 * 命令模式:
 * 		将一个请求封装成一个对象  从而使得你可以用不同的请求对客户进行参数化 ;对请求排队或者记录日志,以及支持可撤销的操作
 * 常见应用:
	1、工作队列,线程池,日程安排
	2、日志请求(系统恢复)
   	当然这里写的demo还有好多不科学的地方 比如撤销操作 判断是否有鸡丁等  这里只是简单叙述一下流程 没有做到深入的讲解 还需要再工作中慢慢体会
 */
public class CommandMode {
	public static void main(String[] args) {
		//营业前准备
		Cook6 cook6 = new Cook6();
		Command6 gbjdcommand  = new gbjdCom6(cook6);
		Command6 gbjdcommand2 = new gbjdCom6(cook6);
		Command6 hsrcommand = new hsrCom6(cook6);
		Command6 hsrcommand2 = new hsrCom6(cook6);
		Waiter6 waiter6 = new Waiter6();
		
		//营业
		waiter6.setOrder(gbjdcommand);
		waiter6.setOrder(gbjdcommand2);
		waiter6.setOrder(hsrcommand);
		waiter6.setOrder(hsrcommand2);
		//取消一份红烧头
		waiter6.cancel(hsrcommand2);
		
		//点菜完了 通知厨师
		waiter6.Notify();
		
		//最后只做了一份红烧肉 宫保鸡丁没了
		
		
	}
}
/*
 * 命令抽象
 */
abstract class Command6{
	protected  String flag;
	protected Cook6 cook;
	public Command6(){
	}
	public Command6(Cook6 cook){
		this.cook = cook;
	}
   public abstract void ExcuCommand();
}

/*
 * 宫保鸡丁
 */
class gbjdCom6 extends Command6{
	public gbjdCom6(Cook6 cook){
		this.flag = "gbjd";
		this.cook = cook;
	}
	public void ExcuCommand() {
		cook.gbjd();
	}
}

/*
 * 红烧肉
 */
class hsrCom6 extends Command6{
	public hsrCom6(Cook6 cook){
		this.flag = "hsr";
		this.cook = cook;
	}
	public void ExcuCommand() {
		cook.hsr();
	}
}

/*
 * 服务员
 */
class Waiter6{
	private List<Command6> commands   = new ArrayList<Command6>();
	public void setOrder(Command6 command){
		//如果是宫保鸡丁 就不做了
		if("gbjd".equals(command.flag)){
			System.out.println("鸡丁没了 不能做宫保鸡丁了");
		}else{
			commands.add(command);
		}
	}
	//取消订单
	public void cancel(Command6 command){
		commands.remove(command);
	}
	//通知厨师做菜
	public void Notify(){
		for (Command6 command : commands) {
			command.ExcuCommand();
		}
	}
}



/*
 * 厨师
 */
class Cook6{
	public void gbjd(){
		System.out.println("宫保鸡丁");
	}
	public void hsr(){
		System.out.println("红烧肉");
	}
}