【工厂模式】工厂方法模式、抽象工厂模式-简单例子

news2025/1/16 15:49:01

简单工厂模式,请跳转到我的另一篇博客【工厂模式】简单工厂模式-简单例子-CSDN博客

四、工厂方法模式

(1)这部分还是不变,创建一个Car接口,和两个实现类。

public interface Car {
   void name();
}

public class WuLing implements Car{
  @Override
  public void name() {
    System.out.println("五菱");
  }
}

public class Tesla implements Car{
  @Override
  public void name() {
    System.out.println("特斯拉");
  }
}

(2)把车工厂提取成一个接口,

public interface CarFactory {
  Car getCar();
}

public class TeslaFactory implements CarFactory{
  @Override
  public Car getCar() {
    return new Tesla();
  }
}


public class WuLingFactory implements CarFactory{
  @Override
  public Car getCar(){
    return new WuLing();
  }
}

(3)这样的话,我再新增一种新车的时候就很方便了。

public class Mobai implements Car {
  @Override
  public void name(){
    System.out.println("mobai");
  }
}

public class MobaiFactory implements CarFactory{
  @Override
  public Car getCar() {
    return new Mobai();
  }
}

(4)创建一个Customer类,

public class Customer {
  public static void main(String[] args) {
    Car car1 = new WuLingFactory().getCar();
    Car car2 = new TeslaFactory().getCar();
    car1.name();
    car2.name();
    Car car3 = new MobaiFactory().getCar();
    car3.name();
  }
}

这样的话,原来的类我们是没有动的,并且随时可以动态扩展,满足开闭原则。

但是实现起来反而是非常麻烦的,因为从下图的目录结构中我们也可以看出,需要创建的类变多了。

画个流程图分析一下,

总结

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它通过定义一个用于创建对象的接口,但是让子类决定实例化哪个类。这样,工厂方法模式允许一个类的实例化延迟到其子类。

在工厂方法模式中,通常会有一个抽象的工厂类,该工厂类定义了一个抽象的方法,用于创建产品对象。具体的产品创建逻辑由子类实现,每个子类负责实例化特定类型的产品。这样,客户端代码可以通过调用工厂方法来创建所需的产品,而无需关心具体的实现细节。

工厂方法模式通常包括以下角色:

  1. 抽象工厂类(Abstract Factory Class):定义了一个抽象的工厂方法,用于创建产品对象。通常是一个接口或抽象类。

  2. 具体工厂类(Concrete Factory Class):实现了抽象工厂类,负责实际创建产品对象的逻辑。每个具体工厂类对应一种产品类型。

  3. 抽象产品类(Abstract Product Class):定义了产品对象的接口或抽象类,描述了产品的公共属性和方法。

  4. 具体产品类(Concrete Product Class):实现了抽象产品类定义的接口或抽象类,是真正被创建的产品对象。

工厂方法模式的优点在于可以将对象的创建逻辑移到子类中,使得主要的工厂类更加通用,而具体的产品实现则可以灵活地扩展和变化。同时,它也遵循了开闭原则,对扩展开放,对修改关闭。

总的来说,工厂方法模式提供了一种更加灵活的对象创建方式,适用于需要根据不同情况创建不同类型对象的场景。

简单工厂模式和工厂方法模式的对比

简单工厂模式(Simple Factory Pattern)和工厂方法模式(Factory Method Pattern)是两种不同的创建型设计模式,它们在对象创建的方式和角色分配上有一些不同之处。

  1. 角色定义

    • 简单工厂模式通常只涉及一个工厂类,该工厂类负责根据客户端的请求创建具体的产品对象。
    • 工厂方法模式引入了抽象工厂类和具体工厂类,使得对象的创建逻辑更加灵活。抽象工厂类定义了一个抽象的工厂方法,而具体的产品创建逻辑则由具体工厂类实现。
  2. 创建逻辑

    • 在简单工厂模式中,工厂类通常包含一个静态方法,根据不同的参数或条件返回不同类型的产品对象。
    • 而在工厂方法模式中,每个具体的产品都有对应的具体工厂类,该类负责创建特定类型的产品对象。这样,对象的创建逻辑被分散到了多个具体工厂类中。
  3. 扩展性

    • 简单工厂模式的扩展性相对较差,如果需要添加新的产品类型,则需要修改工厂类的代码,违反了开闭原则。
    • 工厂方法模式遵循了开闭原则,因为具体的产品创建逻辑在具体工厂类中,所以可以通过添加新的具体工厂类来扩展系统,而不需要修改已有的代码。
  4. 复杂度

    • 简单工厂模式相对于工厂方法模式来说,实现起来较为简单,适用于简单的场景。
    • 工厂方法模式的实现相对复杂一些,但提供了更高的灵活性和可扩展性,适用于需要根据不同情况创建不同类型对象的复杂场景。

总的来说,简单工厂模式适用于简单的对象创建场景,而工厂方法模式更适用于复杂的场景,需要更高的灵活性和可扩展性。

五、抽象工厂模式

(1)创建一个产品接口类,和两个实现类。

public interface PhoneProduct {
  void start();
  void shutdown();
  void call();
  void sendMes();
}

public class XiaomiPhone implements PhoneProduct{
  @Override
  public void start() {
    System.out.println("小米手机开机");
  }

  @Override
  public void shutdown() {
    System.out.println("小米手机关机");
  }

  @Override
  public void call() {
    System.out.println("小米手机打电话");
  }

  @Override
  public void sendMes() {
    System.out.println("小米手机发短信");
  }
}

public class HuaWeiPhone implements PhoneProduct{
  @Override
  public void start() {
    System.out.println("华为手机开机");
  }

  @Override
  public void shutdown() {
    System.out.println("华为手机关机");
  }

  @Override
  public void call() {
    System.out.println("华为手机打电话");
  }

  @Override
  public void sendMes() {
    System.out.println("华为手机发短信");
  }
}

(2)创建一个路由器接口类,和两个实现类。

public interface RouteProduct {
  void start();
  void shutdown();
  void setting();
  void openWife();
}

public class XiaomiRoute implements RouteProduct{
  @Override
  public void start() {
    System.out.println("小米路由器开机");
  }

  @Override
  public void shutdown() {
    System.out.println("小米路由器关机");
  }

  @Override
  public void setting() {
    System.out.println("小米路由器设置");
  }

  @Override
  public void openWife() {
    System.out.println("小米路由器打开wife");
  }
}

public class HuaWeiRoute implements RouteProduct{
  @Override
  public void start() {
    System.out.println("华为路由器开机");
  }

  @Override
  public void shutdown() {
    System.out.println("华为路由器关机");
  }

  @Override
  public void setting() {
    System.out.println("华为路由器设置");
  }

  @Override
  public void openWife() {
    System.out.println("华为路由器打开wife");
  }
}

(3)创建一个抽象工厂接口,已经两个系列产品的实现类。

public interface ProductFactory {
  PhoneProduct phoneProduct();

  RouteProduct routeProduct();
}


public class HuaWeiFactory implements ProductFactory{
  @Override
  public PhoneProduct phoneProduct() {
    return new HuaWeiPhone();
  }

  @Override
  public RouteProduct routeProduct() {
    return new HuaWeiRoute();
  }
}

public class XiaomiFactory implements ProductFactory{
  @Override
  public PhoneProduct phoneProduct() {
    return new XiaomiPhone();
  }

  @Override
  public RouteProduct routeProduct() {
    return new XiaomiRoute();
  }
}

(4)创建一个Client类,

public class Client {
  public static void main(String[] args) {
    System.out.println("----小米产品----");
    XiaomiFactory xiaomiFactory = new XiaomiFactory();
    PhoneProduct phoneProduct = xiaomiFactory.phoneProduct();
    RouteProduct routeProduct = xiaomiFactory.routeProduct();
    phoneProduct.call();
    routeProduct.openWife();

    System.out.println("----华为产品----");
    HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
    PhoneProduct phoneProduct1 = huaWeiFactory.phoneProduct();
    RouteProduct routeProduct1 = huaWeiFactory.routeProduct();
    phoneProduct1.call();
    routeProduct1.openWife();
  }
}

总结

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类。抽象工厂模式属于工厂模式的一种扩展,它通过引入抽象工厂和具体工厂来解决工厂方法模式中只能创建单一产品的局限性。

在抽象工厂模式中,有两个关键的角色:

  1. 抽象工厂(Abstract Factory):定义了创建一系列产品的方法,每个方法对应一种产品。
  2. 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体的产品。

与工厂方法模式不同的是,抽象工厂模式中一个具体工厂可以创建多个不同类型的产品,这些产品之间通常有关联性,属于同一个产品族。

适用场景:

  1. 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  2. 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

抽象工厂模式的优点包括:

  • 客户端与具体产品的实现相分离,客户端通过抽象工厂接口操作产品,可以方便地更换产品系列。
  • 符合开闭原则,增加新的产品族很方便,只需要增加对应的具体工厂类即可。

但是,抽象工厂模式也有一些缺点:

  • 难以支持新种类产品的变化,因为需要修改抽象工厂接口及其所有的实现。
  • 增加了系统的复杂度,引入了更多的抽象概念和类。

总的来说,抽象工厂模式适用于需要创建一系列相关或依赖对象的场景,其中产品的组合可能会变化,但产品之间的关联性固定的情况。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文献补充材料怎么查找获取

最近很多同学求助外文文献补充材料,有的同学在学校提供的资源中能找到全文却无法下载文献的补充材料,这是因为该校只收录了全文而没有收录补充材料。那么文献补充材料怎么查找又如何获取呢?请看本文的经验分享: 1、文献的补充材料…

在Linux系统中搜索当前路径及其子目录下所有PDF文件中是否包含特定字符串

目录标题 方法一:pdfgrep方法二:使用find和xargs与pdftotext(将PDF转换为文本)组合,然后用grep搜索 方法一:pdfgrep pdfgrep -ri "rockchip" .方法二:使用find和xargs与pdftotext&am…

Yolov8项目实践——基于yolov8与OpenCV实现目标物体运动热力图

概述 在数据驱动和定位的世界中,对数据进行解释、可视化和决策的能力变得日益重要。这表明,使用正确的工具和技术可能是项目成功的关键。在计算机视觉领域,存在许多技术来解释从视频(包括录像、流媒体或实时视频)中获…

【HC32L110】华大低功耗单片机启动文件详解

本文主要记录华大低功耗单片机 HC32L110 的 汇编启动过程,包括startup_hc32l110启动文件详细注释 目录 1.启动文件的作用2.堆栈定义2.1 栈2.2堆 3.向量表4.复位程序5.中断服务程序6.堆栈初始化启动过程详解7.1从0地址开始7.2在Reset_Handler中干了啥? 8.…

ContextMenuStrip内容菜单源对象赋值学习笔记(含源码)

一、前言 MetroTileItem属于第三方控件,无法定义ContextMenuStrip属性 想实现某子项点击菜单时,与源控件(按钮metroTileItem)的某值对应,用于动态控制按钮的状态或方法 1.1 效果 二、实现方法 2.1 方法1 (代码,说明见注释) private void metroTileItem_MouseDown(o…

python_django中小学家校互动系统vue_flask家校联系

实现了一个完整的家校互动系统,其中主要有作业信息模块、学校管理员模块、学生学籍模块、学生成绩模块、学科模块、系统新闻模块、系统公告模块、校内新闻模块、校内公告模块、用户表模块、token表模块、关于我们模块、收藏表模块、年级模块、家长模块、教师模块、互…

openlayers学习(一)

首先感谢大佬们写的文章,博客链接已在文章最后贴出,在接下来的内容中,我将会引用其中的一些定义结论。 之前文章写过一个Arcgis api for js的小demo,openlayers项目代码就继续在写这个小demo框架上。 openlayers官网 初始化地图…

Flink学习(六)-容错处理

前言 Flink 是通过状态快照实现容错处理 一、State Backends 由 Flink 管理的 keyed state 是一种分片的键/值存储,每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中。 一种基于 RocksDB 内嵌 key/value 存储将其工作状态保存在磁盘上&#x…

聚观早报 | 华为Pura70系列先锋计划;月之暗面升级Kimi

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 4月19日消息 华为Pura70系列先锋计划 月之暗面升级Kimi OPPO Find X7将推白色版本 波士顿动力推出人形机器人 v…

sql-labs(1-8关)

mysql数据结构 在练习靶场前我们需要了解以下mysql数据库结构,mysql数据库5.0以上版本有一个自带的数据库叫做information_schema,该数据库下面有两个表一个是tables和columns。tables这个表的table_name字段下面是所有数据库存在的表名。table_schema字段下是所有…

面试: Hashtable vs ConcurrentHashMap

一、Hashtable和ConcurrentHashMap的不同和相同点 Hashtable 与 ConcurrentHashMap 都是线程安全的Map 集合。Hashtable 并发度低,整个Hashtable对应一把锁,同一时刻,只能有一个线程操作它。1.8之前ConcurrentHashMap使用了Segment 数组&…

爱普生发布一款16位MCU产品用于大电流LED驱动

精工爱普生发布一款内置Flash存储器的16位微控制器S1C17M13 该新品可以提供最大56mA的驱动电流用于驱动发光二极管(LED) 以往爱普生的微处理器大多继承了液晶驱动器电路,但近来随着工业自动化和家用设备使用7段LED显示的数量大幅增加,爱普生也推出了对应…

pdf加水印怎么加?自己原创的PDF资料分享到网络上需要采取一些版权保护的措施,添加水印就是个不错的选择

一,水印的基本概念 水印通常是一种用于标识文件来源、版权信息或防止非法复制的标记。它可以是文字、图形或图像等形式,以半透明或半淡化的方式嵌入到文件中,既不影响文件的正常阅读,又能起到标识和保护的作用。 二,…

如何查看Debian Linux的内核版本

2024年4月19日,周五上午 uname -r

测试数据整理--chatgpt 构造sql语句导出数据库数据

在测试过程中,我们有时候需要准备一些测试数据,若从系统中直接导出Excel数据,数据往往庞大且需要整合,不好整理,于是我们直接去数据库中查询一些表,数据整合后直接导出结果会更方便。 我们今天就 用 chatg…

【EdgeBox-8120AI-TX2】Ubuntu18.04 + ROS_ Melodic + 星秒PAVO2单线激光 雷达评测

大家好,我是虎哥,好久不见,最近这断时间出现了一点变故,开始自己创业,很多事需要忙,所以停更了大约大半年,最近一切已经理顺,所以我还是抽空继续我之前的FLAG,CSDN突破十…

矩阵混乱度(熵值)代码计算

1、先回顾下熵值的数据公式: 2、jax.numpy代码 注意的点:熵值计算的输入的必须是归一化的正值 import jax.numpy as jnp import jax def _entroy(probs):log_probs jnp.log2(jnp.maximum(1.0e-30, probs))mean_sum_plogp jnp.mean(- jnp.sum(log_pro…

OpenHarmony鸿蒙南向开发案例:【智能窗户通风设备】

样例简介 本文档介绍了安全厨房案例中的相关智能窗户通风设备,本安全厨房案例利用轻量级软总线能力,将两块欧智通V200Z-R/BES2600开发板模拟的智能窗户通风设备和燃气告警设备组合成。当燃气数值告警时,无需其它操作,直接通知软总…

java实现chatGPT SDK

搭建一个 ChatGPT-SDK 组件工程,专门用于封装对 OpenAI 接口的使用。由于 OpenAI 接口本身较多,并有各类配置的设置,所以开发一个共用的 SDK 组件,更合适我们在各类工程中扩展使用 整个流程为:以会话模型为出口&#x…

spring boot后端开发基础

spring boot后端开发基础 Spring Boot一、开发步骤二、Web分析三、跨域问题四、HTTP协议五、Web服务器六、响应前端请求七、springboot常用注解创建一个简单的RESTful API服务层和数据访问层配置类和Bean定义响应体和路径变量 Spring Boot 一、开发步骤 创建项目 添加依赖 项…