设计模式之禅PK之创建类
创建类设计模式
- 创建类模式:
- 工厂方法模式
- 建造者模式
- 抽象工厂模式
- 单例模式
- 原型模式
- 创建者模式的功能:
- 提供对象的创建和管理职责
- 工厂方法模式、抽象工厂方法模式、建造者模式他们之间有较多的相似性,容易混淆
- 单例模式是要保持在内存中只有一个对象;原型模式是要通过复制的方式产生一个新的对象
【工厂模式】VS【建造者模式】
- 对比
- 工厂方法模式:注重的是整体对象的创建
- 建造者模式:注重是部件构建的过程,旨在通过一步步地精确构造创建出一个复杂的对象
- 举例简单说明
- 假如要制造一个超人
- 工厂方法模式:直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人
- 建造者模式:组装手、头、脚、躯干等部分,然后再把内裤外穿
- 假如要制造一个超人
- 具体通过逻辑来PK
比较内容 | 工厂方法模式生产超人 | 建造者模式组装超人 |
---|---|---|
类图 | ![]() | ![]() |
类图解释 | 1.正宗的工厂方法模式 2.定义一个接口,然后定义两个实现,通过超人制造工厂制造超人 | 1.经典的建造者模式 2.哎!不对劲,通用的模式上抽象的是建造者与产品没有关系呀!!!是的,但是可以加强,在抽象建造者上使用了模板方法模式,每一个建造者都必须返回一个产品,但是产品如何制造的,由各个建造者自己负责 |
代码 | 见【工厂模式超人代码】 | 见【建造模式超人代码】 |
代码
-
工厂模式超人代码
-
ISuperMan
package com.peng.pk_gc; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public interface ISuperMan { // 特殊技能 public void specialTalent(); }
-
AdultSuperMan
package com.peng.pk_gc; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class AdultSuperMan implements ISuperMan { // 成年超人 @Override public void specialTalent() { System.out.println("成年超人:超人力大无穷!"); } }
-
ChildSuperMan
package com.peng.pk_gc; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class ChildSuperMan implements ISuperMan { // 儿童超人 @Override public void specialTalent() { System.out.println("儿童超人:刀枪不入,快速运动"); } }
-
SuperManFactory
package com.peng.pk_gc; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class SuperManFactory { // 定义一个生产超人的工厂 public static ISuperMan createSuperMan(String type) { // 根据输入参数产生不同的超人 if ("adultsuperman".equalsIgnoreCase(type)) { // 生产成人超人 return new AdultSuperMan(); } else if ("childsuperman".equalsIgnoreCase(type)) { // 生产儿童超人 return new ChildSuperMan(); } return null; } }
-
Client
package com.peng.pk_gc; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class Client { public static void main(String[] args) { // 模拟生产超人--生产一个成年超人 ISuperMan adultSuperMan = SuperManFactory .createSuperMan("adultsuperman"); adultSuperMan.specialTalent(); // 模拟生产超人--生产一个儿童超人 ISuperMan childSuperMan = SuperManFactory .createSuperMan("childsuperman"); childSuperMan.specialTalent(); } }
-
执行结果
成年超人:超人力大无穷! 儿童超人:刀枪不入,快速运动
-
-
建造模式超人代码
-
SuperMan
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class SuperMan { // 超人的躯体 private String body; // 超人的特殊技能 private String specialTalent; // 超人的标志 private String specialSymbol; public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getSpecialTalent() { return specialTalent; } public void setSpecialTalent(String specialTalent) { this.specialTalent = specialTalent; } public String getSpecialSymbol() { return specialSymbol; } public void setSpecialSymbol(String specialSymbol) { this.specialSymbol = specialSymbol; } }
-
Builder
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public abstract class Builder { // 定义一个超人的应用 protected final SuperMan superMan = new SuperMan(); // 构建超人的躯体 public void setBody(String body) { this.superMan.setBody(body); } // 构建超人的特殊技能 public void setSpecialTalent(String specialTalent) { this.superMan.setSpecialTalent(specialTalent); } // 构建超人的特殊标记 public void setSymbol(String specialSymbol) { this.superMan.setSpecialSymbol(specialSymbol); } // 构建一个完整的超人 public abstract SuperMan getSuperMan(); }
-
AdultSuperMan
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class AdultSuperMan extends Builder { @Override public SuperMan getSuperMan() { super.superMan.setBody("强壮的躯体"); super.superMan.setSpecialTalent("会飞行"); super.superMan.setSpecialSymbol("胸前的S标记"); return super.superMan; } }
-
ChildSuperMan
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class ChildSuperMan extends Builder { @Override public SuperMan getSuperMan() { super.superMan.setBody("强壮的躯体"); super.superMan.setSpecialTalent("刀枪不入"); super.superMan.setSpecialSymbol("胸前的小S标记"); return super.superMan; } }
-
Director
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class Director { // 成年超人建造者的应用 private static Builder adultSuperMan = new AdultSuperMan(); // 儿童超人建造者的应用 private static Builder childSuperMan = new ChildSuperMan(); // 建造一个成年超人 public static SuperMan getAdultSuperMan() { return adultSuperMan.getSuperMan(); } // 建造一个儿童超人 public static SuperMan getChildSuperMan() { return childSuperMan.getSuperMan(); } }
-
Client
package com.peng.pk_jz; /** * @author kungfu~peng * @data 2017年12月8日 * @description */ public class Client { public static void main(String[] args) { // 建造一个成人超人 SuperMan adultSuperMan = Director.getAdultSuperMan(); System.out.println("成人超人~~"); System.out.println(adultSuperMan.getBody()); System.out.println(adultSuperMan.getSpecialSymbol()); System.out.println(adultSuperMan.getSpecialTalent()); // 建造一个儿童超人 SuperMan childSuperMan = Director.getChildSuperMan(); System.out.println("儿童超人~~"); System.out.println(childSuperMan.getBody()); System.out.println(childSuperMan.getSpecialSymbol()); System.out.println(childSuperMan.getSpecialTalent()); } }
-
执行结果
成人超人~~ 强壮的躯体 胸前的S标记 会飞行 儿童超人~~ 强壮的躯体 胸前的小S标记 刀枪不入
-
最佳实践
- 工厂方法模式和建造者模式都属于对象创建类模式,都用来创建对象,但是他们之间的区别还是比较明显的
工厂方法模式 | 建造者模式 | |
---|---|---|
意图不同 | 关注的是产品的整体,无需关注超人是怎样建造出来的 【对象创建的粗线条应用】 | 一个具体的产品的生产依赖各个部件的产生以及装配顺序,他关注的是一步步的组装起来 【对象创建的细线条应用】 |
产品的复杂度不同 | 单一性质的产品 粗粒度 | 复合产品 细粒度 |
实际应用中选择 | 只需要产品,不关注产品的产生过程 | 需要详细关注一个产品的生产、安装 |
声明
- 摘自秦小波《设计模式之禅》第2版;
- 仅供学习,严禁商业用途;
- 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;