设计模式之禅之创建类PK【工厂模式VS建造者模式】 ﹏ヽ暗。殇╰゛Y 2022-06-02 12:07 225阅读 0赞 # 设计模式之禅PK之创建类 # ### 创建类设计模式 ### * 创建类模式: * 工厂方法模式 * 建造者模式 * 抽象工厂模式 * 单例模式 * 原型模式 * 创建者模式的功能: * 提供对象的创建和管理职责 * 工厂方法模式、抽象工厂方法模式、建造者模式他们之间有较多的相似性,容易混淆 * 单例模式是要保持在内存中只有一个对象;原型模式是要通过复制的方式产生一个新的对象 ### 【工厂模式】VS【建造者模式】 ### * 对比 * 工厂方法模式:注重的是整体对象的创建 * 建造者模式:注重是部件构建的过程,旨在通过一步步地精确构造创建出一个复杂的对象 * 举例简单说明 * 假如要制造一个超人 * 工厂方法模式:直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人 * 建造者模式:组装手、头、脚、躯干等部分,然后再把内裤外穿 * 具体通过逻辑来PK <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">比较内容</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">工厂方法模式生产超人</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">建造者模式组装超人</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">类图</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/Nn23DmU.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/h2twaUR.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> </tr> <tr style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:1px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204); background-color:rgb(248,248,248)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">类图解释</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">1.正宗的工厂方法模式<br> 2.定义一个接口,然后定义两个实现,通过超人制造工厂制造超人</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">1.经典的建造者模式<br> 2.哎!不对劲,通用的模式上抽象的是建造者与产品没有关系呀!!!是的,但是可以加强,在抽象建造者上使用了模板方法模式,每一个建造者都必须返回一个产品,但是产品如何制造的,由各个建造者自己负责</td> </tr> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">代码</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">见【工厂模式超人代码】</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">见【建造模式超人代码】</td> </tr> </tbody> </table> ### 代码 ### * 工厂模式超人代码 * 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标记 刀枪不入 ### 最佳实践 ### * 工厂方法模式和建造者模式都属于对象创建类模式,都用来创建对象,但是他们之间的区别还是比较明显的 <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"> </th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">工厂方法模式</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">建造者模式</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">意图不同</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">关注的是产品的整体,无需关注超人是怎样建造出来的<br> 【对象创建的粗线条应用】</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">一个具体的产品的生产依赖各个部件的产生以及装配顺序,他关注的是一步步的组装起来<br> 【对象创建的细线条应用】</td> </tr> <tr style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:1px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204); background-color:rgb(248,248,248)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">产品的复杂度不同</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">单一性质的产品<br> 粗粒度</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">复合产品<br> 细粒度</td> </tr> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">实际应用中选择</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">只需要产品,不关注产品的产生过程</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">需要详细关注一个产品的生产、安装</td> </tr> </tbody> </table> ### 声明 ### * 摘自秦小波《设计模式之禅》第2版; * 仅供学习,严禁商业用途; * 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
相关 创建类模式:抽象工厂模式VS建造者模式。 抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关系构件过程,只关心什么产品由什么工厂生产即可。而建造者 本是古典 何须时尚/ 2024年02月18日 23:58/ 0 赞/ 28 阅读
相关 设计模式之禅之跨战区PK【门面模式VS中介者模式】 设计模式之禅跨战区PK 前言 创建类模式描述如何创建对象 行为类模式关注如何管理对象的行为 结构类模式则侧重于如何建立一个软件结构 实际的应 绝地灬酷狼/ 2022年06月02日 12:26/ 0 赞/ 174 阅读
相关 设计模式之禅之结构类PK【装饰模式VS适配器模式】 设计模式之禅PK之结构类 结构类设计模式 结构类模式: 适配器模式 桥梁模式 组合模式 装饰 不念不忘少年蓝@/ 2022年06月02日 12:26/ 0 赞/ 170 阅读
相关 设计模式之禅之结构类PK【代理模式VS装饰模式】 设计模式之禅PK之结构类 结构类设计模式 结构类模式: 适配器模式 桥梁模式 组合模式 装饰 Bertha 。/ 2022年06月02日 12:25/ 0 赞/ 185 阅读
相关 设计模式之禅之行为类PK【观察者模式VS责任链模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 悠悠/ 2022年06月02日 12:07/ 0 赞/ 196 阅读
相关 设计模式之禅之行为类PK【策略模式VS状态模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 爱被打了一巴掌/ 2022年06月02日 12:07/ 0 赞/ 189 阅读
相关 设计模式之禅之行为类PK【命令模式VS策略模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 红太狼/ 2022年06月02日 12:07/ 0 赞/ 154 阅读
相关 设计模式之禅之创建类PK【抽象工厂模式VS建造者模式】 设计模式之禅PK之创建类 创建类设计模式 创建类模式: 工厂方法模式 建造者模式 抽象工厂模式 矫情吗;*/ 2022年06月02日 12:07/ 0 赞/ 173 阅读
相关 设计模式之禅之创建类PK【工厂模式VS建造者模式】 设计模式之禅PK之创建类 创建类设计模式 创建类模式: 工厂方法模式 建造者模式 抽象工厂模式 ﹏ヽ暗。殇╰゛Y/ 2022年06月02日 12:07/ 0 赞/ 226 阅读
相关 设计模式之禅【建造者模式】 真刀实枪之建造者模式 变化是永恒的--悍马车的私人订制 汽车的启动,停止,喇叭声音,引擎声音都有客户控制 先看类图吧,简单设计 末蓝、/ 2022年06月02日 09:45/ 0 赞/ 212 阅读
还没有评论,来说两句吧...