09.简单工厂模式与工厂方法模式
- 人工智能
- 2025-08-06 14:21:02

道生一,一生二,二生三,三生万物。——《道德经》
最近小米新车亮相的消息可以说引起了不小的轰动,我们在感慨SU7充满土豪气息的保时捷设计的同时,也深深的被本土品牌的野心和干劲所鼓舞。 今天我们就接着这个背景,开启造车的终极幻想,尝试拆解一下工厂模式中最基础的两部分:简单工厂模式和工厂方法模式。
一言
简单工厂模式:定义一个创建对象的类,由它来封装实例化对象的行为代码。 工厂方法模式:将对象实例化推迟到子类。
为什么要用工厂模式 Wayne造车
如果现在有一个需求,要我们模拟一段造车的代码,你想怎么做? 首先自然是分析需求:
既然我们要造车,那车的种类必然很多(油车?电车?核动力?!)造车的工序我们暂时就粗暴的认为只有准备材料、加工、组装和测试四个步骤造好了车,我们还需要通过4S店卖出去 三寸反骨三条需求刚刚讲完,反骨仔立马站了起来:“这也太简单了!我来!” 于是他这样实现了需求: 首先他清醒的将车做成了抽象:
代码实现(反例) public abstract class Car { protected String name;//名字 //准备原材料,不同的汽车材料不同,所以做成抽象方法 public abstract void prepare(); public void process(){//加工 System.out.println(name+" processing"); } public void assemble(){//组装 System.out.println(name+" assemble"); } public void check(){//测试 System.out.println(name+" check"); } public void setName(String name) { this.name = name; } }然后是车具体的实现:
public class OilCar extends Car{ @Override public void prepare() { System.out.println("准备优秀的内燃机"); } } public class EleCar extends Car{ @Override public void prepare() { System.out.println("准备优秀耐用的电池"); } }最后是4S店
public class FourS { //构造器 public FourS() { Car car = null; String orderType; do { orderType=getType(); System.out.println("=============================="); if (orderType.equals("ele")){ car = new EleCar(); car.setName("新能源汽车"); }else if (orderType.equals("oil")){ car = new OilCar(); car.setName("燃机汽车"); }else { break; } car.prepare(); car.process(); car.assemble(); car.check(); }while (true); } private String getType(){ try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("=============================="); System.out.println("input car type"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); } return ""; } }不得不说,反骨仔确实有所成长,不再是那个100%的毛躁汉子了,但是这种设计是否存在问题? 我们先看下运行的结果: 业务的实现自然是没有问题的,实现过程也非常容易理解,然后一切的一切发展的都很顺利,我们的车一经上市就大受欢迎,在各方面都是遥遥领先。于是我们决定,扩展业务,“多开几家4S店,再狠狠的赚他一笔,初步预估先开1000家店吧,靓仔啊,你去把这个事情落实一下。奥,对了,你们这个项目现在发展前景非常好,我们已经在和奔驰、宝马、宾利、法拉利等老牌的汽车公司展开了深度合作,以后可能还要把他们的品牌融合到我们的产品中…”。 反骨仔看着自己的代码,汗流浃背了。 可能有的同学已经看到了问题的关键: 这种设计从根本上违反了OCP原则,每一次小的扩展就会更改大量代码。 有的同学可能会说,我ctrl CV 大法包治百病,那如果我们后面真的在核动力汽车领域有了突破,这部分扩展的代码是不是要改一千多次? 所以说,修改代码并非不可接受,但是如果我们在其它地方也有创建Car,就意味着这些地方都要修改,而创建Car的地方往往有很多处。
基于简单工厂模式的优化 思路分析
好了,我们已经发现了问题下一步就是如何解决这个问题了。 在思路上,我们可以尝试把创建Car对象封装在一个类中,这样我们有新的Car种类时,只需要修改该类即可,其它创建Car对象的代码就不需要修改了。这其实就是简单工厂模式的基本思路。
核心代码 public class FourS1 { Car car = null; public FourS1(){ setFactory(); } public void setFactory(){ String orderType=""; do{ orderType = getType(); System.out.println("=============================="); car = SimpleFactory.createCar(orderType); if (car!=null){ car.prepare(); car.process(); car.assemble(); car.check(); }else { System.out.println("订购汽车失败"); break; } }while (true); } //可以获取客户希望订购的披萨种类 private String getType(){ try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("=============================="); System.out.println("input pizza type"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); } return ""; } }结束了吗
当然没有,我们看似通过简单方法模式解决了大部分的核心问题,但是却忽略了“最新消息”里最致命的那句:“奥,对了,你们这个项目现在发展前景非常好,我们已经在和奔驰、宝马、宾利、法拉利等老牌的汽车公司展开了深度合作,以后可能还要把他们的品牌融合到我们的产品中…” 也就是说,我们后续要求的输出是奔驰的燃机汽车、宝马的燃机汽车、宝马的新能源汽车、奔驰的核动力汽车… 反观简单工厂模式,是否有实力接得住这一波需求? 其实硬要接也不是接不住,无非是多几个SimpleFactory。但是实际操作起来必然很难维护。严格意义上讲,采用简单工厂模式硬接这种需求实际上也是违反OCP原则的。
基于工厂方法模式的优化 思路分析
当与各大品牌合作之后,造车过程似乎变得复杂了起来。首先奔驰和宝马是想和我们合作,而他们之间并没有展开合作,这意味着我们要为他们定制不同的4S店和造车工厂。
核心代码 public abstract class AbsFourS { public abstract Car createPizza(String orderType); public AbsFourS() { Car car = null; String orderType; do { orderType=getType(); System.out.println("=============================="); car=createPizza(orderType); car.prepare(); car.process(); car.assemble(); car.check(); }while (true); } private String getType(){ try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("=============================="); System.out.println("input car type"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); } return ""; } } public class BenzWayne4s extends AbsFourS { @Override public Car createPizza(String orderType) { Car car = null; if(orderType.equals("ele")){ car = new BenzEleCar(); car.setName("奔驰与Wayne联名推出的新能源汽车"); }else if (orderType.equals("oil")){ car = new BenzOilCar(); car.setName("奔驰与Wayne联名推出的内燃机汽车"); } return car; } } public class BmwWayne4s extends AbsFourS { @Override public Car createPizza(String orderType) { Car car = null; if(orderType.equals("ele")){ car = new BMWEleCar(); car.setName("宝马与Wayne联名推出的新能源汽车"); }else if (orderType.equals("oil")){ car = new BMWEleCar(); car.setName("宝马与Wayne联名推出的内燃机汽车"); } return car; } }测试结果
结
我们在前面用了大量的篇幅介绍了简单工厂模式和工厂方法模式。记得我在上一篇介绍建造者模式时,卖了个关子,就是关于建造者模式和抽象工厂模式的区别。 抽象工厂模式可以将简单工厂模式和工厂方法模式的优势整合起来,它的理念是基于简单工厂模式和工厂方法模式的,这也正是我花了大量篇幅介绍它们的原因。 抽象工厂模式实现对产品家族的创建,一个产品家族是具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。 也就是说: • 建造者模式比较关注 产品的 “组装过程”; • 抽象工厂模式只关注什么工厂生产了什么产品; 这一点,在我下周继续拆解抽象工厂模式之后,我们可以一起再来体会一下。
关注我,共同进步,每周至少一更。——Wayne
09.简单工厂模式与工厂方法模式由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“09.简单工厂模式与工厂方法模式”