当前位置: 首页 > news >正文

【设计模式深度剖析】【A】【创建型】【对比】| 工厂模式重点理解产品族的概念

回 顾:创建型设计模式

1.单例模式👈️

2.工厂方法模式👈️

3.抽象工厂模式👈️

4.建造者模式👈️

5.原型模式👈️

👈️上一篇:原型模式    |   👉️下一篇:代理模式

目录

  • 创建型模式对比
  • 概览
  • 1. 工厂方法模式
    • 类图
    • 1.1 抽象工厂角色:SuperManFactory:
    • 1.2 具体工厂类
      • 1.2.1 某具体工厂类:AdultSuperManFactory.java
      • 1.2.2 某具体工厂类:ChildSuperManFactory.java
    • 1.3 抽象产品角色:ISuperMan.java
    • 1.4 具体产品角色
      • 1.4.1 某具体产品类:AdultSuperMan.java
      • 1.4.2 某具体产品类:ChildSuperMan.java
    • 1.5 测试类:DemoTest.java
  • 2. 建造者模式
    • 类图
    • 2.1 抽象建造者:Builder.java
    • 2.2 具体建造者角色
      • 2.2.1 某具体建造者:AdultSuperManBuilder.java
      • 2.2.2 某具体建造者:ChildSuperManBuilder.java
    • 2.3 产品角色类:SuperMan.java
    • 2.4 导演者、指挥官角色:Director.java
    • 2.5 测试类:DemoTest.java
  • 3. 抽象工厂模式
    • 类图
    • 3.1 抽象工厂角色:HeroFactory.java
    • 3.2 具体工厂角色
      • 3.2.1 某具体工厂:AdultHeroFactory.java
      • 3.2.2 某具体工厂:ChildHeroFactory.java
    • 3.3 抽象产品-超人类:ISuperMan.java
      • 3.3.1 具体产品:AdultSuperMan.java
      • 3.3.2 具体产品:ChildSuperMan.java
    • 3.4 抽象产品-蜘蛛侠类:ISuperMan.java
      • 3.4.1 具体产品:AdultSpiderMan.java
      • 3.4.2 具体产品:ChildSpiderMan.java
    • 3.5 测试类

创建型模式对比

本文示例源码

创建型模式包括单例模式工厂方法模式抽象工厂模式建造者模式原型模式,这些模式都能够提供对象的创建和管理职责。

其中:

  1. 单例模式和原型模式非常容易理解,单例模式是在内存中保持只有一个对象;
  2. 原型模式是通过复制的方式产生一个新的对象,这两个模式不容易混淆,在此不做对比。

工厂方法模式抽象工厂模式建造者模式具有较多的相似性,它们之间的区别如下。

  1. 工厂方法模式注重的是整体对象的创建方法
  2. 建造者模式注重的是部件构建的过程,旨在通过一步步精确构造,创建出一个复杂的对象。
  3. 抽象工厂模式实现对产品家族的创建,抽象工厂模式不关心构建过程,只关心什么产品由什么工厂生产即可

下面分别使用工厂方法模式、建造者模式和抽象工厂模式制造超人,通过对比可以清晰地认识它们之间的差别。

工厂方法模式通过不同的工厂生产不同的超人,主要注重创建方法。

建造者模式则需要通过不同的建造者组装超人的各部分组件,然后通过导演类调用建造者的具体建造方法建造超人,最后通过建造者返回超人。建造者模式注重创建的过程。

抽象工厂模式通过不同的工厂生产一系列超级英雄,注重产品族的完整性

当一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。(多个产品族1,2,3,产品族4… ,每个产品族都有A、B、C等等产品),
如果产品族中只有一种产品,则抽象工厂模式就退化为工厂方法模式

建造者角色抽象了产品各个属性的配置方法,并为客户端提供build()方法,按需构建所需对象。

抽象工厂模式针对的是生产不同产品类型,但是这些产品类型有不同的族别(或者叫做等级之类的),

比如生产汽车、摩托车,这是两种产品,如果仅仅生产这两种产品类型(也可以理解为笼统的、不区分产品族,或者说没有产品族的概念,或者说仅有一种产品族),使用工厂方法模式即可;

但是如果有了族别的差别,比如:运动型(Sporty)一族、豪华型(Luxury)一族、越野型(Off-Road)一族、经济型(Economy)一族、城市型(Urban)一族、旅行型(Touring)一族、复古型(Retro)一族,每一族都有对应的汽车产品和摩托车产品这种多种产品族的场景,每种产品族有对应的产品类型,此种情况,需要使用抽象工厂模式

在汽车和摩托车这两个产品类型中,除了运动型(Sporty)之外,还可以抽象出多种共有的产品族,这些产品族通常基于车辆的用途、风格、功能或者性能来划分。以下是一些示例:

  1. 豪华型(Luxury)
    • 豪华型汽车通常具有高级的内饰、舒适的座椅、先进的驾驶辅助系统和高级的音响系统。
    • 豪华型摩托车也追求同样的豪华体验,可能包括高级材料、精细的工艺、舒适的骑行位置和高级的电子设备。
  2. 越野型(Off-Road)
    • 越野型汽车通常具有强大的动力系统、高离地间隙、四驱系统以及适合越野驾驶的轮胎和悬挂系统。
    • 越野型摩托车(也称为冒险型或越野摩托车)也拥有类似的特性,用于穿越崎岖的地形和越野驾驶。
  3. 经济型(Economy)
    • 经济型汽车旨在提供高效、省油的驾驶体验,通常具有较小的排量、较轻的车身和较低的维护成本。
    • 经济型摩托车也注重燃油效率和成本控制,适合日常通勤和短途旅行。
  4. 城市型(Urban)
    • 城市型汽车通常设计紧凑、易于停放,并且具有良好的城市驾驶性能,如灵活的操控和快速的加速。
    • 城市型摩托车(也称为街车或城市通勤摩托车)也适合城市环境,提供轻便、灵活的驾驶体验。
  5. 旅行型(Touring)
    • 旅行型汽车拥有宽敞的内部空间、舒适的座椅和大量的储物空间,适合长途旅行和多人出行。
    • 旅行型摩托车(也称为长途摩托车或巡航摩托车)也提供了舒适的骑行环境、大量的储物空间和长途骑行的稳定性。
  6. 复古型(Retro)
    • 复古型汽车和摩托车都采用了经典的设计元素和风格,旨在唤起人们对过去的怀念和向往。

这些产品族都是汽车和摩托车共有的,可以根据市场需求和产品定位来设计和生产。通过使用抽象工厂模式,可以方便地管理和扩展这些产品族,以满足不同客户的需求。
但,如果只是简单的一个产品族,或者未区别产品族的情况,工厂方法模式即可满足需求。

概览

  • 工厂方法模式
    • 使用工厂方法模式制造超人,管理一个产品族产品生产
  • 建造者模式
    • 使用建造者模式制造超人:构造超人各个部分
  • 抽象工厂模式
    • 使用抽象工厂模式制造超人和蜘蛛侠,管理不同产品族产品生产

1. 工厂方法模式

本示例源码

类图

下述内容用于实现任务描述:使用工厂方法模式制造超人,其整体类图如下:

在这里插入图片描述

1.1 抽象工厂角色:SuperManFactory:

上层工厂接口,定义生产产品的标准,也就是定义了一个接口方法,生产超人的方法。

而且抽象工厂角色类,只规定标准,定义生产产品的方法,

它不关心具体怎样生产,那是具体工厂类该干的事情。

实现类也就是具体工厂类按照标准去实现即可。

public interface SuperManFactory {// 生产超人ISuperMan createSuperMan();
}

1.2 具体工厂类

实现抽象工厂,某具体工厂,会创建某具体产品实例

1.2.1 某具体工厂类:AdultSuperManFactory.java

某具体工厂类:成年超人工厂类,生产成年超人

public class AdultSuperManFactory implements SuperManFactory {// 制作成年超人@Overridepublic ISuperMan createSuperMan() {return new AdultSuperMan();}
}

1.2.2 某具体工厂类:ChildSuperManFactory.java

某具体工厂类:未成年超人工厂类,生产未成年超人

public class ChildSuperManFactory implements SuperManFactory {// 制造未成年人超人@Overridepublic ISuperMan createSuperMan() {return new ChildSuperMan();}
}

1.3 抽象产品角色:ISuperMan.java

抽象产品接口,规定了产品该有的功能,而不关心该功能的具体实现,

怎样实现该功能,那是具体产品类的事情,

实现类也就是具体产品类按照规定的标准去实现该功能即可。

public interface ISuperMan {// 超人的特殊能力void specialTalent();
}

1.4 具体产品角色

对抽象产品要求的标准(抽象方法)进行具体实现

1.4.1 某具体产品类:AdultSuperMan.java

某具体产品类,成年超人产品类,实现了抽象产品接口,完成了接口规定的方法

public class AdultSuperMan implements ISuperMan {@Overridepublic void specialTalent() {// 实现特殊能力System.out.println("成年超人力大无穷、可以飞行!");}
}

1.4.2 某具体产品类:ChildSuperMan.java

某具体产品类,未成年超人产品类,实现了抽象产品接口,完成了接口规定的方法

public class ChildSuperMan implements ISuperMan {@Overridepublic void specialTalent() {// 实现特殊能力System.out.println("小超人可以快速运动");}
}

1.5 测试类:DemoTest.java

测试抽象工厂类:

抽象工厂定义了产品生产方法;

具体工厂实现抽象工厂接口,实现了产品实例生产的方法。

public class DemoTest {public static void main(String[] args) {HeroFactory adultFactory = new AdultHeroFactory();ISuperMan adultSuperMan = adultFactory.createSuperMan();ISpiderMan adultSpiderMan = adultFactory.createSpiderMan();adultSuperMan.specialTalent();adultSpiderMan.launchSilk();System.out.println("--------------------");HeroFactory childFactory = new ChildHeroFactory();ISuperMan childSuperMan = childFactory.createSuperMan();ISpiderMan childSpiderMan = childFactory.createSpiderMan();childSuperMan.specialTalent();childSpiderMan.launchSilk();}
}
/* Output:
成年超人力大无穷、能飞行
成年蜘蛛侠发射出100米长的蛛丝
--------------------
未成年超人快速移动
幼年蜘蛛侠发射出5米长的蛛丝
*///~

2. 建造者模式

本示例源码

类图

下述内容用于实现任务描述:使用建造者模式制造超人,其整体类图如下:

在这里插入图片描述

2.1 抽象建造者:Builder.java

抽象建造者(Builder)角色,抽象了所有属性配置的方法,并提供build()方法,供客户端调用按需获取所需产品实例。

public abstract class Builder {protected final SuperMan superMan = new SuperMan();// 建造身体public abstract void setBody();// 建造能力public abstract void setSpecialTalent();// 建造标志public abstract void setSpecialSymbol();// 获得创建好的超人public SuperMan build() {return this.superMan;}
}

2.2 具体建造者角色

2.2.1 某具体建造者:AdultSuperManBuilder.java

某具体建造者,成年超人构建者,按照抽象建造者的标准提供具体实现,来构建成年超人

public class AdultSuperManBuilder extends Builder {@Overridepublic void setBody() {superMan.setBody("强壮的身体");}@Overridepublic void setSpecialTalent() {this.superMan.setSpecialTalent("可以飞行");}@Overridepublic void setSpecialSymbol() {superMan.setSpecialSymbol("胸前带S标记");}
}

2.2.2 某具体建造者:ChildSuperManBuilder.java

某具体建造者,未成年超人构建者,按照抽象建造者的标准提供具体实现,来构建未成年超人

public class ChildSuperManBuilder extends Builder {@Overridepublic void setBody() {this.superMan.setBody("灵敏的身子");}@Overridepublic void setSpecialTalent() {this.superMan.setSpecialTalent("快速运动");}@Overridepublic void setSpecialSymbol() {this.superMan.setSpecialSymbol("胸前带小S标记");}
}

2.3 产品角色类:SuperMan.java

产品(Product)角色,超人类

public class SuperMan {@Getter@Setter// 超人的身体private String body;@Getter@Setter// 超人的特殊能力private String specialTalent;@Getter@Setter// 超人的标志private String specialSymbol;@Overridepublic String toString() {return this.getBody() + "," +this.getSpecialTalent() + "," +this.getSpecialSymbol();}
}

2.4 导演者、指挥官角色:Director.java

客户端,调用建造者实例的方法来获得所需对象

public class Director {private Builder builder;public SuperMan buildSuperMan(String type) {if (type.equals("child")) {builder = new ChildSuperManBuilder();} else if (type.equals("adult")) {builder = new AdultSuperManBuilder();} else {return null;}builder.setBody();builder.setSpecialTalent();builder.setSpecialSymbol();return builder.build();}
}

2.5 测试类:DemoTest.java

package com.polaris.designpattern.list1.creational.comparison.builder;public class DemoTest {public static void main(String[] args) {Director director = new Director();SuperMan adultSuperMan = director.buildSuperMan("adult");System.out.println("成年超人:" + adultSuperMan);SuperMan childSuperMan = director.buildSuperMan("child");System.out.println("小超人:" + childSuperMan);}
}/* Output:
成年超人:强壮的身体,可以飞行,胸前带S标记
小超人:灵敏的身子,快速运动,胸前带小S标记
*///~

3. 抽象工厂模式

本示例源码
这里的示例中,有两个产品族:成年和未成年的英雄,每个产品族工厂都能创建超人和蜘蛛侠两类产品

类图

下述内容用于实现任务描述:使用抽象工厂模式制造超人和蜘蛛侠,其整体类图如下:

在这里插入图片描述

3.1 抽象工厂角色:HeroFactory.java

约定了生产两种产品,超人和蜘蛛侠这两种产品

public interface HeroFactory {// 生产超人ISuperMan createSuperMan();// 生产蜘蛛侠ISpiderMan createSpiderMan();
}

3.2 具体工厂角色

3.2.1 某具体工厂:AdultHeroFactory.java

针对成年英雄产品族,生产成年英雄,

实现生产超人和蜘蛛侠这两种产品的方法,

因此该工厂生产成年(产品族)的超人和蜘蛛侠

public class AdultHeroFactory implements HeroFactory {@Overridepublic ISuperMan createSuperMan() {return new AdultSuperMan();}@Overridepublic ISpiderMan createSpiderMan() {return new AdultSpiderMan();}
}

3.2.2 某具体工厂:ChildHeroFactory.java

针对未成年英雄产品族,生产未成年英雄,

实现生产超人和蜘蛛侠这两种产品的方法,

因此该工厂生产未成年(产品族)的超人和蜘蛛侠

public class ChildHeroFactory implements HeroFactory {@Overridepublic ISuperMan createSuperMan() {return new ChildSuperMan();}@Overridepublic ISpiderMan createSpiderMan() {return new ChildSpiderMan();}
}

3.3 抽象产品-超人类:ISuperMan.java

规定了超人产品所具备的功能

public interface ISuperMan {// 超人的特殊能力public abstract void specialTalent();
}

3.3.1 具体产品:AdultSuperMan.java

成年一族产品,超人产品,成年超人产品类

public class AdultSuperMan implements ISuperMan {@Overridepublic void specialTalent() {System.out.println("成年超人力大无穷、能飞行");}
}

3.3.2 具体产品:ChildSuperMan.java

未成年一族产品,超人产品,未成年超人产品类

public class ChildSuperMan implements ISuperMan {@Overridepublic void specialTalent() {System.out.println("未成年超人快速移动");}
}

3.4 抽象产品-蜘蛛侠类:ISuperMan.java

规定了蜘蛛侠产品所具备的功能

public interface ISpiderMan {// 发出蛛丝public abstract void launchSilk();
}

3.4.1 具体产品:AdultSpiderMan.java

成年一族产品,蜘蛛侠产品,成年蜘蛛侠产品类

public class AdultSpiderMan implements ISpiderMan {@Overridepublic void launchSilk() {System.out.println("成年蜘蛛侠发射出100米长的蛛丝");}
}

3.4.2 具体产品:ChildSpiderMan.java

未成年一族产品,蜘蛛侠产品,未成年蜘蛛侠产品类

public class ChildSpiderMan implements ISpiderMan {@Overridepublic void launchSilk() {System.out.println("幼年蜘蛛侠发射出5米长的蛛丝");}
}        

3.5 测试类

public class DemoTest {public static void main(String[] args) {HeroFactory adultFactory = new AdultHeroFactory();ISuperMan adultSuperMan = adultFactory.createSuperMan();ISpiderMan adultSpiderMan = adultFactory.createSpiderMan();adultSuperMan.specialTalent();adultSpiderMan.launchSilk();System.out.println("--------------------");HeroFactory childFactory = new ChildHeroFactory();ISuperMan childSuperMan = childFactory.createSuperMan();ISpiderMan childSpiderMan = childFactory.createSpiderMan();childSuperMan.specialTalent();childSpiderMan.launchSilk();}
}
/* Output:
成年超人力大无穷、能飞行
成年蜘蛛侠发射出100米长的蛛丝
--------------------
未成年超人快速移动
幼年蜘蛛侠发射出5米长的蛛丝
*///~

回 顾:创建型设计模式

1.单例模式👈️

2.工厂方法模式👈️

3.抽象工厂模式👈️

4.建造者模式👈️

5.原型模式👈️

👈️上一篇:原型模式    |   👉️下一篇:代理模式

相关文章:

  • memmove使⽤和模拟实现
  • 数据结构和算法基础(二)
  • 基于 Java 的浏览器——JxBrowser使用分享
  • Sass是什么?有哪些优缺点?
  • 【代码随想录算法训练营第37期 第十七天 | LeetCode110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和】
  • python数据类型之列表
  • 海外媒体发稿的关键步骤和投稿策略:如何撰写高质量的新闻稿?国外软文发布平台有哪些?
  • 如何同一局域网下ssh远程登录
  • 提取COCO 数据集的部分类
  • 移动云ECS主机:未来云计算的驱动力
  • 局部放电试验变频电源
  • 牛客NC391 快乐数【simple 模拟法 Java/Go/PHP】
  • el-table 合并单元格_以合并属性值相同行为例
  • ysoserial下载和使用
  • PHP开发安全:专家级代码审计策略与方法
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Babel配置的不完全指南
  • CentOS6 编译安装 redis-3.2.3
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Linux CTF 逆向入门
  • Linux快速复制或删除大量小文件
  • text-decoration与color属性
  • v-if和v-for连用出现的问题
  • Windows Containers 大冒险: 容器网络
  • 阿里云购买磁盘后挂载
  • 你对linux中grep命令知道多少?
  • HanLP分词命名实体提取详解
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​力扣解法汇总946-验证栈序列
  • (3)STL算法之搜索
  • (四)模仿学习-完成后台管理页面查询
  • .equals()到底是什么意思?
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core 中插件式开发实现
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .net 调用php,php 调用.net com组件 --
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • [android] 天气app布局练习
  • [Android]Android开发入门之HelloWorld
  • [Android]创建TabBar
  • [BT]BUUCTF刷题第9天(3.27)
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)
  • [C# 基础知识系列]专题十六:Linq介绍
  • [C#]winform部署PaddleOCRV3推理模型
  • [C++]C++类基本语法
  • [emuch.net]MatrixComputations(7-12)
  • [IE编程] 打开/关闭IE8的光标浏览模式(Caret Browsing)
  • [iOS]把16进制(#871f78)颜色转换UIColor
  • [JS] 常用正则表达式集(一)
  • [LeetCode] NO. 169 Majority Element
  • [Linux] CE知识随笔含Ansible、防火墙、VIM、其他服务
  • [Luogu 2816]宋荣子搭积木