设计模式之禅PK之创建类
创建类设计模式
- 创建类模式:
- 工厂方法模式
- 建造者模式
- 抽象工厂模式
- 单例模式
- 原型模式
- 创建者模式的功能:
- 提供对象的创建和管理职责
- 工厂方法模式、抽象工厂方法模式、建造者模式他们之间有较多的相似性,容易混淆
- 单例模式是要保持在内存中只有一个对象;原型模式是要通过复制的方式产生一个新的对象
【抽象工厂模式】VS【建造者模式】
- 对比
- 抽象工厂模式:实现对产品家族的创建,一个产品家族是这样一系列对象--具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可
- 建造者模式:按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新的产品
举例来比较一下
- 现在有个需求,要生产汽车,不同工厂生产不同的汽车,宝马车生产宝马车,奔驰车生产奔驰车,车不仅具有不同的品牌,而且具有不同的用途分类,如商务用车Van,运动型车SUV,我们按照这个需求分别用两种设计模式分别来实现一下
- 先来对比一下类图
抽象工厂模式 | 建造者模式 | |
---|---|---|
类图 |
具体代码实现
-
抽象工厂模式生产汽车
-
ICar
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public interface ICar { // 汽车生产商--名牌 public String getBand(); //汽车的型号 public String getModel(); }
-
AbsBMW
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public abstract class AbsBMW implements ICar { private final static String BMW_BAND = "宝马汽车"; @Override public String getBand() { return BMW_BAND; } @Override public abstract String getModel(); }
-
AbsBenz
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public abstract class AbsBenz implements ICar { private final static String BENZ_BAND = "奔驰汽车"; @Override public String getBand() { return BENZ_BAND; } @Override public abstract String getModel(); }
-
BMWSuv
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description 宝马商务车 */ public class BMWSuv extends AbsBMW { private final static String X_SEARIES = "X系列车型SUV"; @Override public String getModel() { return X_SEARIES; } }
-
BMWVan
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description 宝马商务车 */ public class BMWVan extends AbsBMW { private final static String SEVENT_SEARIES = "7系列车型商务车"; @Override public String getModel() { return SEVENT_SEARIES; } }
-
BenzSuv
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description 宝马商务车 */ public class BenzSuv extends AbsBMW { private final static String G_SEARIES = "G系列车型SUV"; @Override public String getModel() { return G_SEARIES; } }
-
BenzVan
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description 宝马商务车 */ public class BenzVan extends AbsBMW { private final static String R_SEARIES = "R系列车型商务车"; @Override public String getModel() { return R_SEARIES; } }
-
CarFactory
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public interface CarFactory { // 生产SUV public ICar createSuv(); // 生产Van public ICar createVan(); }
-
BMWFactory
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class BMWFactory implements CarFactory { @Override public ICar createSuv() { return new BMWSuv(); } @Override public ICar createVan() { return new BMWVan(); } }
-
BenzFactoy
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class BenzFactory implements CarFactory { @Override public ICar createSuv() { return new BenzSuv(); } @Override public ICar createVan() { return new BenzVan(); } }
-
Client
package com.peng.pk_cxgc; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class Client { public static void main(String[] args) { CarFactory factory = null; factory = new BenzFactory(); System.out.println("=========生产一辆奔驰SUV========="); System.out.println(factory.createSuv().getModel()); System.out.println("=========生产一辆奔驰Van========="); System.out.println(factory.createVan().getModel()); factory = new BMWFactory(); System.out.println("=========生产一辆宝马SUV========="); System.out.println(factory.createSuv().getModel()); System.out.println("=========生产一辆宝马Van========="); System.out.println(factory.createVan().getModel()); } }
-
执行结果
=========生产一辆奔驰SUV========= G系列车型SUV =========生产一辆奔驰Van========= R系列车型商务车 =========生产一辆宝马SUV========= X系列车型SUV =========生产一辆宝马Van========= 7系列车型商务车
-
-
建造者模式生产汽车
-
ICar
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public interface ICar { // 汽车车轮 public String getWheel(); // 汽车引擎 public String getEngine(); }
-
Car
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class Car implements ICar { // 汽车车轮 private String wheel; // 汽车引擎 private String engine; // 构造函数传递参数 public Car(String wheel, String engine) { super(); this.wheel = wheel; this.engine = engine; } @Override public String getWheel() { return this.wheel; } @Override public String getEngine() { return this.engine; } @Override public String toString() { return "车的轮子是:" + this.wheel + ",车的引擎是:" + this.engine; } }
-
CarBuilder
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public abstract class CarBuilder { // 设计蓝图 private BluePaint bp; public Car buildCar() { return new Car(buildEngine(), buildWhel()); } protected abstract String buildWhel(); protected abstract String buildEngine(); // 接收一份设计蓝图 public void receiveBluepaint(BluePaint bp) { this.bp = bp; } // 获得设计蓝图--真正的建造者才能查看蓝图 public BluePaint getBp() { return bp; } }
-
BenzBuilder
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class BenzBuilder extends CarBuilder { @Override protected String buildWhel() { return super.getBp().getWheel(); } @Override protected String buildEngine() { return super.getBp().getEngine(); } }
-
BMWBuilder
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class BMWBuilder extends CarBuilder { @Override protected String buildWhel() { return super.getBp().getWheel(); } @Override protected String buildEngine() { return super.getBp().getEngine(); } }
-
BulePaint
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class BluePaint { // 车轮的生产要求 private String wheel; // 引擎的生产要求 private String engine; public String getWheel() { return wheel; } public void setWheel(String wheel) { this.wheel = wheel; } public String getEngine() { return engine; } public void setEngine(String engine) { this.engine = engine; } }
-
Director
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class Director { // 声明对建造者的引用 private CarBuilder benzBuilder = new BenzBuilder(); private CarBuilder bmwBuilder = new BMWBuilder(); // 生产奔驰SUV public ICar createBenzSuv() { // 制造出汽车 return createCar(benzBuilder, "奔驰的轮胎", "奔驰的引擎"); } // 生产宝马商务车 public ICar createBMWVan() { return createCar(bmwBuilder, "宝马车的轮胎", "宝马车的引擎"); } // 生产出混合车型 public ICar createComplexCar() { return createCar(bmwBuilder, "宝马的轮胎", "奔驰的引擎"); } // 生产车辆 private ICar createCar(CarBuilder cb, String wheel, String engine) { // 导演怀揣设计蓝图 BluePaint bp = new BluePaint(); bp.setEngine(engine); bp.setWheel(wheel); System.out.println("获得生产蓝图!"); cb.receiveBluepaint(bp); return cb.buildCar(); } }
-
Client
package com.peng.pk_jz2; /** * @author kungfu~peng * @data 2017年12月9日 * @description */ public class Client { public static void main(String[] args) { // 定义出导演类 Director director = new Director(); // 生产一辆奔驰SUV System.out.println("======生产奔驰SUV====="); System.out.println(director.createBenzSuv()); // 生产一辆宝马商务 System.out.println("======生产宝马商务====="); System.out.println(director.createBMWVan()); // 生产一辆混合车型 System.out.println("======生产混合车型====="); System.out.println(director.createComplexCar()); } }
-
执行结果
======生产奔驰SUV===== 获得生产蓝图! 车的轮子是:奔驰的引擎,车的引擎是:奔驰的轮胎 ======生产宝马商务===== 获得生产蓝图! 车的轮子是:宝马车的引擎,车的引擎是:宝马车的轮胎 ======生产混合车型===== 获得生产蓝图! 车的轮子是:奔驰的引擎,车的引擎是:宝马的轮胎
-
- 代码写完了,现在看看两者有哪些注意的地方
抽象共产模式生产汽车 | 建造者模式生产汽车 |
---|---|
抽象共产模式把一辆车认为是一个完整、不可拆分的对象。它注重完整性,一个产品一旦找到一个工厂生产,那就是固定的型号,不会出现一个生产宝马的工厂生产出来奔驰车的情况 | 按照建造者设计模式设计一个生产车辆需要把车辆进行拆分,拆分成引擎和轮胎(暂且有这两个部件),然后由建造者进行建造,想要什么车,只要有设计蓝图即可,马上就可以建造出相应的车出来。它注重的是对零件的装配、组合、封装,他从一个构件装配角度看待一个对象 |
最佳实践
- 我们在抽象工厂模式使用“工厂”来描述建造者,在建造者模式中使用“车间”来描述建造者
- 关于工厂与车间
工厂 | 车间 | |
---|---|---|
观察的角度 | 更高层次去看对象的构建,对一个领导者来说,不用关心一个工厂到底是怎样具体的生产一个产品的 | 它是由车间组成,不同的车间完成不同的任务,一个完整的汽车需要引擎车间和轮胎车间的配合才能完成,他们的配合的基础就是汽车的设计蓝图,而蓝图掌握在车间主任(导演)的手上,建造者模式更关心的是建造的过程 |
尺度大小 | 尺度大:它关注产品的整体 | 尺度小:它关注构建过程 |
应用场景 | 屏蔽对象的创建过程,只提供一个封装良好的对象 | 可以用在装配方面 |
声明
- 摘自秦小波《设计模式之禅》第2版;
- 仅供学习,严禁商业用途;
- 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;