【设计模式深度剖析】【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 {
    // 制作成年超人
    @Override
    public ISuperMan createSuperMan() {
        return new AdultSuperMan();
    }
}

1.2.2 某具体工厂类:ChildSuperManFactory.java

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

public class ChildSuperManFactory implements SuperManFactory {
    // 制造未成年人超人
    @Override
    public 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 {

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

1.4.2 某具体产品类:ChildSuperMan.java

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

public class ChildSuperMan implements ISuperMan {

    @Override
    public 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 {

    @Override
    public void setBody() {
        superMan.setBody("强壮的身体");
    }

    @Override
    public void setSpecialTalent() {
        this.superMan.setSpecialTalent("可以飞行");
    }

    @Override
    public void setSpecialSymbol() {
        superMan.setSpecialSymbol("胸前带S标记");
    }
}

2.2.2 某具体建造者:ChildSuperManBuilder.java

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

public class ChildSuperManBuilder extends Builder {

    @Override
    public void setBody() {
        this.superMan.setBody("灵敏的身子");
    }

    @Override
    public void setSpecialTalent() {
        this.superMan.setSpecialTalent("快速运动");
    }

    @Override
    public 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;

    @Override
    public 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 {

    @Override
    public ISuperMan createSuperMan() {
        return new AdultSuperMan();
    }

    @Override
    public ISpiderMan createSpiderMan() {
        return new AdultSpiderMan();
    }
}

3.2.2 某具体工厂:ChildHeroFactory.java

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

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

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

public class ChildHeroFactory implements HeroFactory {

    @Override
    public ISuperMan createSuperMan() {
        return new ChildSuperMan();
    }

    @Override
    public 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 {

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

3.3.2 具体产品:ChildSuperMan.java

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

public class ChildSuperMan implements ISuperMan {

    @Override
    public 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 {

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

3.4.2 具体产品:ChildSpiderMan.java

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

public class ChildSpiderMan implements ISpiderMan {

    @Override
    public 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.原型模式👈️

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634337.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript基础(九)

冒泡排序 用例子比较好理解: var arry[7,2,6,3,4,1,8]; //拿出第一位数7和后面依次比较,遇到大的8就换位,8再与后面依次比较,没有能和8换位的数,再从下一位2依次与下面的数比较。 console.log(排列之前:arry); for (…

Unity Render入门

概述 在unity中渲染相关的组件是和Render关联的,比如我们常见的3D模型中的MeshRender,UI中的RenderCanvas等都是和Render相关联的,相信在unity的学习过程中,一定看到过非常多和Render相关的内容,那让我们学习一下这部…

GRPC服务使用

目标: 1.什么是GRPC服务? 2.安卓客户端怎么不熟GRPC服务? 3.怎么生成GRPC的java类? 一、什么是GRPC服务? GRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。 支持长…

【Linux】-Tomcat安装部署[12]

目录 简介 安装 安装部署JDK环境 解压并安装Tomcat 简介 Tomcat是由Apache开发的一个Servlet容器,实现了对Servlet和JSP的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 简单来说&#…

vscode 插件-02 html

open in brower 安装后可以在vscode中,使用浏览器打开编辑的.html文件,以查看效果。 Live Preview 实现网页的实时渲染显示功能,即实时预览。

K8S认证|CKA题库+答案| 1. 权限控制RBAC

1、权限控制RBAC 您必须在以下Cluster/Node上完成此考题: Cluster Master node Worker node k8s master …

ptrade从零开始学习量化交易第16期【ptrade策略API介绍之set_slippage-设置滑点】

设置函数 更加详细的调用方法,后续会慢慢整理。 也可找寻博主历史文章,搜索关键词使用方案,比如本文涉及函数set_slippage! 感谢关注,咨询免费开通量化回测与获取实盘权限,欢迎和博主联系! …

沃尔玛卖家必学:自养号测评环境搭建技巧,助你销量翻倍

沃尔玛,作为国际零售行业的翘楚,其平台的销售业绩对卖家来说意义非凡。然而,在现今这个充满竞争的商业环境中,众多卖家在沃尔玛平台上努力追求销量的过程中,常常面临着重重障碍和挑战。他们迫切需要在短时间内找到一种…

免费发布web APP的四个途径(Python和R)

免费发布数据分析类🌐web APP的几个途径📱 数据分析类web APP目前用来部署生信工具,统计工具和预测模型等,便利快捷,深受大家喜爱。而一个免费的APP部署途径,对于开发和测试APP都是必要的。根据笔者的经验…

junams 文件上传 (CNVD-2020-24741)

漏洞环境搭建:vulfocus 发现这个页面后,通过访问IP:Port/admin.php,登录后台 通过默认用户名密码admin:admin进行登录 登录后台后,主要思路就是找到网站的文件上传点,然后去上传一句话木马,或者找到命令执…

AI大模型:GPT引领,百模征战

从 2022 年底 ChatGPT 横空出世,到 2023 年一整年的大模型热潮,在科技的巨浪中,大模型技术如同一颗璀璨的明星,迅速起并引领着一场前所未有的技术革命。大模型如同推动创新的引擎,将科技的边界不断拓展。 01 大模型演…

[数据集][目标检测]弹簧上料检测数据集VOC+YOLO格式142张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):142 标注数量(xml文件个数):142 标注数量(txt文件个数):142 标注类别…

自动驾驶决策规划算法——二次规划

自动驾驶决策规划算法第二章第二节(中) 参考线算法_哔哩哔哩_bilibili 动态规划开辟的凸空间如下,两条橙色线之间: 黄色的点就意味着L的上下界,物理意义是当轨迹ss1时,L的范围应该是(Lmin1,Lmax1)之间,这个范围就是开辟…

Git使用教程:最详细、最傻瓜、最浅显、真正手把手教

Git是什么?SVN与Git最主要的区别?在windows上如何安装Git?如何操作?远程仓库创建与合并分支 一、Git是什么 Git是目前世界上最先进的分布式版本控制系统。 工作原理/流程: workspace:工作区Index/Stage&#xff1a…

Jetbrains 拥抱 LLM ,推出的AI Assistant,这样使用!

ai assistant激活成功后,如图 ai assistant渠道:https://web.52shizhan.cn/activity/ai-assistant 在去年五月份的 Google I/O 2023 上,Google 为 Android Studio 推出了 Studio Bot 功能,使用了谷歌编码基础模型 Codey,Codey 是…

3d模型旋转世界坐标输入怎么用?怎么设置?---模大狮模型网

在3D建模和动画领域,模型的旋转是常见的操作之一。而当我们谈到模型的旋转时,经常会涉及到世界坐标和局部坐标这两个概念。世界坐标是描述物体在三维空间中绝对位置的坐标系统,而局部坐标则是相对于物体自身坐标系的坐标系统。本文将详细介绍…

(六)Spring教程——Spring IoC容器(中)

(一)Spring教程——Spring框架简介 (二)Spring教程——Spring框架特点 (三)Spring教程——依赖注入与控制反转 (四)Spring教程——控制反转或依赖注入与Java的反射技术 (五)Spring教程——Spring IoC容器(上) (六)Spring教程——Spring IoC容器(中) (七)…

axios案例应用

1、Spring概述 Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层。Spring JDBC 以及业务层事务管理等众多…

Removing Smallest Multiples

题目描述: 给你一个集合 S &#xff0c;其中包含前 n 个正整数1, 2 。 您可以对 S 执行以下操作任意次数(可能为零)&#xff1a; #include<iostream> #include<cstring> #include<algorithm> #define int long long using namespace std; int t,n,sum; bo…

前端vue基于uni-app的地图定位与距离测算技术研究

前端vue基于uni-app的地图定位与距离测算技术研究 摘要&#xff1a;随着移动互联网的普及和智能终端设备的多样化&#xff0c;移动应用的需求也在不断增长。uni-app作为一款跨平台的前端开发框架&#xff0c;为开发者提供了极大的便利。本文着重探讨了如何在uni-app中实现地图…