顾客进入餐厅,告诉服务员,来一份西红柿鸡蛋。然后等着吃就行了。
顾客根本不需要知道做一份西红柿炒鸡蛋的过程。
厨师在后面咔咔捣鼓,饭就做好了。
我们来看看后厨都干了些什么吧!
后厨的厨师会做100道菜:佛跳桥,蚂蚁上树,麻婆豆腐等等等;但是老板说今日餐厅提供的菜品有:西红柿炒鸡蛋,辣椒炒牛肉。厨师只能做这两道菜:西红柿炒鸡蛋,辣椒炒牛肉。
前台告诉厨师搞一份西红柿炒鸡蛋,厨师刚好会,直接开火烧油,咔咔操作。
建造者模式就是这个效果,客户进入餐厅,只需要下单他想吃的菜(必须菜单上有),就可以吃到了。其他的事情完全不需要操心。
企业使用建造者模式封装某个技术(比如查询工具包),后入职的程序员只需要调用提供的方法(根据Id查询、根据年龄查询、分页查询),就可以实现自己想要的查询效果。一点都不需要操心其方法是如何实现的。
那么代码是如何实现这种效果呢,下面会给一个案例,通过此案例,希望你学会解构公司代码设计,甚至学会自己封装一套。
- 老板说今天餐厅只卖 西红柿炒鸡蛋,辣椒炒牛肉两个菜品
/**
* 辣椒炒牛肉
*/
@Data
public class CapsicumBeef {
/**
* 牛肉
*/
private String beef;
/**
* 辣椒
*/
private String capsicum;
}
/**
* 西红柿炒鸡蛋
*/
@Data
public class TomatoEggs {
/**
* 西红柿
*/
private String tomato;
/**
* 鸡蛋
*/
private String egg;
}
- 制定菜单
/**
* 老板对厨房要求的菜单
*/
@Data
public class Menu {
// 番茄炒蛋
public TomatoEggs tomatoEggs;
// 辣椒炒牛肉
public CapsicumBeef capsicumBeef;
}
- 厨房能完成的菜品
/**
* 厨房对前台提供的菜单
*/
public interface Builder {
/**
* 获取菜单
*/
Menu getMenu();
/**
* 构建西红柿鸡蛋汤
* @param tomatoEggs
* @return
*/
Builder buildTomatoEggs(TomatoEggs tomatoEggs);
/**
* 构建辣椒炒牛肉
* @param capsicumBeef
* @return
*/
Builder buildCapsicumBeef(CapsicumBeef capsicumBeef);
}
- 厨师Ove准备预制菜
/**
* 厨师Ove做辣椒炒牛肉和西红柿鸡蛋
*/
public class Ove implements Builder {
Menu menu = new Menu();
@Override
public Menu getMenu() {
return menu;
}
@Override
public Builder buildTomatoEggs(TomatoEggs tomatoEggs) {
menu.setTomatoEggs(tomatoEggs);
return this;
}
@Override
public Builder buildCapsicumBeef(CapsicumBeef capsicumBeef) {
menu.setCapsicumBeef(capsicumBeef);
return this;
}
}
- 前台准备好给客户的菜单
/**
* 前台
*/
public class Director {
// 调用厨师
Builder builder = new Ove();
// 厨师开始做西红柿炒蛋
Menu creatTomatoEggs(TomatoEggs tomatoeggs){
tomatoeggs.setTomato("西红柿");
tomatoeggs.setEgg("鸡蛋");
builder.buildTomatoEggs(tomatoeggs);
return builder.getMenu();
}
// 厨师开始做西红柿炒蛋
Menu creatcCapsicumBeef(CapsicumBeef capsicumBeef){
capsicumBeef.setCapsicum("朝天椒");
capsicumBeef.setBeef("牛后腿肉");
builder.buildCapsicumBeef(capsicumBeef);
return builder.getMenu();
}
}
- 客户下单
/**
* 顾客John下单
*/
public class Consumer {
public static void main(String[] args) {
// 召唤前台工作人员
Director director = new Director();
// 点一份西红柿鸡蛋
TomatoEggs tomEggs = new TomatoEggs();
// 前台下单
Menu menu = director.creatTomatoEggs(tomEggs);
System.out.println(menu);
}
}
打印结果:Menu{tomatoEggs=TomatoEggs{tomato='西红柿', egg='2个鸡蛋'}, capsicumBeef=null}
/**
* 顾客Jay下单
*/
public class Consumer {
public static void main(String[] args) {
// 召唤前台工作人员
Director director = new Director();
// 点辣椒炒肉
CapsicumBeef capsicumBeef = new CapsicumBeef();
// 前台下单
Menu menu = director.creatcCapsicumBeef(capsicumBeef);
System.out.println(menu);
}
}
打印Menu{tomatoEggs=null, capsicumBeef=CapsicumBeef{beef='牛后腿肉', capsicum='朝天椒'}}
实际上你可以发现,想要那个菜,就调用哪个接口,这就是这个项目设计后暴露出来的接口,最普通的程序员仅仅需要调用这些接口,就可以完成基础开发了。而你,我的朋友,已经会设计程序了。这就是架构师的工作内容:面对一个业务场景,考虑设计出最好的方案,保证后续开发的便捷性,可维护性等等。
如果你的代码工作是,独立承担一个完全新的需求开发,之前项目中从没有相关的代码实现,那么就可以考虑使用设计模式等等思想。如果你知识在原有项目上拓展小功能,项目结构你是无法变动的,就老实写吧。后面有时间了考虑代码重构。
最暴力的开发方式就是:活生生的new一大堆,然后简单的调用,一点点设计的思想都没有,刚开始看似完成了功能,后面拓展后代码量一多,代码就不忍直视了。