文章目录
命令模式情景
- 命令模式情景
- 命令模式实战
- 不使用命令模式写法
- 使用命令模式写法
把逻辑实现与操作进行分离, 降低耦合方便扩展. 以数据驱动的方式命令对象, 使用构造函数传递给调用者. 调用者再提供相应的实现为命令执行具体的操作方法.
命令模式实战模拟在餐厅中点餐交给厨师的场景. 顾客只需点不同的菜系, 店小二把不同的菜系写菜单上, 通过菜单下命令, 不同的厨师进行炒菜.
不使用命令模式写法public class XiaoEr {
private Logger logger = LoggerFactory.getLogger(XiaoEr.class);
private Map cuisineMap = new ConcurrentHashMap();
public void order(int cuisine) {
// 广东(粤菜)
if (1 == cuisine) {
cuisineMap.put(1, "广东厨师,烹饪鲁菜,宫廷最大菜系,以孔府风味为龙头");
}
// 江苏(苏菜)
if (2 == cuisine) {
cuisineMap.put(2, "江苏厨师,烹饪苏菜,宫廷第二大菜系,古今国宴上最受人欢迎的菜系。");
}
// 山东(鲁菜)
if (3 == cuisine) {
cuisineMap.put(3, "山东厨师,烹饪鲁菜,宫廷最大菜系,以孔府风味为龙头.");
}
// 四川(川菜)
if (4 == cuisine) {
cuisineMap.put(4, "四川厨师,烹饪川菜,中国最有特色的菜系,也是民间最大菜系。");
}
}
public void placeOrder() {
logger.info("菜单:{}", JSON.toJSONString(cuisineMap));
}
}
直接使用if else 进行判断不同的菜系.
使用命令模式写法使用命令模式拆解为三大块, 命令实现者(菜品), 具体逻辑实现(厨师), 命令调用者(店小二). uml图如下 . 抽象命令定义: 菜品接口
public interface ICuisine {
// 烹调 制作
void cook();
}
具体命令的实现(菜品)
public class GuangDoneCuisine implements ICuisine {
private ICook cook;
public GuangDoneCuisine(ICook cook) {
this.cook = cook;
}
public void cook() {
cook.doCooking();
}
}
public class JiangSuCuisine implements ICuisine {
private ICook cook;
public JiangSuCuisine(ICook cook) {
this.cook = cook;
}
public void cook() {
cook.doCooking();
}
}
public class ShangDongCuisine implements ICuisine {
private ICook cook;
public ShangDongCuisine(ICook cook) {
this.cook = cook;
}
public void cook() {
cook.doCooking();
}
}
public class SiChuanCuisine implements ICuisine {
// 实现的类中都有添加了一个厨师类(ICook)
private ICook cook;
public SiChuanCuisine(ICook cook) {
this.cook = cook;
}
public void cook() {
// 操作命令(烹饪菜品)
cook.doCooking();
}
}
抽象实现者接口 (厨师接口 )
public interface ICook {
void doCooking();
}
实现者具体实现(四类厨师)
public class GuangDongCook implements ICook {
public void doCooking() {
System.out.println("广东厨师, 宫廷最大菜系");
}
}
public class JiangSuCook implements ICook {
public void doCooking() {
System.out.println("江苏厨师, 烹饪苏菜,宫廷第二大菜系");
}
}
public class ShanDongCook implements ICook {
public void doCooking() {
System.out.println("山东厨师. 鲁味..");
}
}
public class SiChuanCook implements ICook {
public void doCooking() {
System.out.println("四川厨师 民间最大菜系");
}
}
调用者(小二)
public class XiaoEr {
//通过外部将菜品和厨师传递进来而进行具体的调用
private List cuisineList = new ArrayList();
public void order(ICuisine cuisine) {
// 菜品的添加
cuisineList.add(cuisine);
}
public synchronized void placeOrder() {
for (ICuisine cuisine : cuisineList) {
// 菜单执行烹饪
cuisine.cook();
}
cuisineList.clear();
}
}
测试类
public class ApiTest {
@Test
public void test() {
// 菜系 菜品与厨师的组合
ICuisine guangDongCuisine = new GuangDongCuisine(new GuangDongCook());
ICuisine jiangSuCuisine = new JiangSuCuisine(new JiangSuCook());
ICuisine shangDongCuisine = new ShangDongCuisine(new ShanDongCook());
ICuisine siChuanCuisine = new SiChuanCuisine(new SiChuanCook());
// 点单 由小二进行操作点单,xiaoEr.order(guangDoneCuisine);,这里分别添加了四种菜品,给小二
XiaoEr xiaoEr = new XiaoEr();
xiaoEr.order(guangDongCuisine);
xiaoEr.order(jiangSuCuisine);
xiaoEr.order(shangDongCuisine);
xiaoEr.order(siChuanCuisine);
// 下单 具体命令实现的操作
xiaoEr.placeOrder();
}
}
测试结果如下
广东厨师, 宫廷最大菜系 江苏厨师, 烹饪苏菜,宫廷第二大菜系 山东厨师. 鲁味… 四川厨师 民间最大菜系