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

简单工厂模式,请跳转到我的另一篇博客【工厂模式】简单工厂模式-简单例子-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.mfbz.cn/a/558691.html

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

相关文章

深入刨析 mysql 底层索引结构B+树

文章目录 前言一、什么是索引?二、不同索引结构对比2.1 二叉树2.2 平衡二叉树2.3 B-树2.4 B树 三、mysql 的索引3.1 聚簇索引3.2 非聚簇索引 前言 很多人看过mysql索引的介绍:hash表、B-树、B树、聚簇索引、主键索引、唯一索引、辅助索引、二级索引、联…

C#语法知识之循环语句

5、循环语句 文章目录 1、while思考1 斐波那契数列思考2 判断一个数是否为质数思考3 找出100以内的质数 2、do...while3、for思考1 找水仙花数思考2 乘法表 1、while 1、作用 让代码重复去执行 2、语法相关 while(bool类型值){//当满足条件时,就会执行while语句…

大话设计模式-里氏代换原则

里氏代换原则(Liskov Substitution Principle,LSP) 概念 里氏代换原则是面向对象设计的基本原则之一,由美国计算机科学家芭芭拉利斯科夫(Barbara Liskov)提出。这个原则定义了子类型之间的关系&#xff0…

linux下使用qt+mpv调用GPU硬件解码

linux下GPU硬件解码接口,常用的有vdpau和vaapi。 mpv是基于mplayer开发的一个播放器。此外,mpv还提供了函数库libmpv,通过使用libmpv可以编写一个简单的播放器。 基于qtlibmpv的demo,官方例子代码如下:https://github.…

Java maven项目打包自动测试并集成jacoco生成代码测试覆盖度报告

引入Junit 引入 junit5 单元测试依赖 <properties><junit.version>5.10.2</junit.version><jacoco.version>0.8.12</jacoco.version></properties><dependencies><!-- 单元测试 --><dependency><groupId>org.jun…

JUC 线程间通信

前言 本篇文章我将解释《并发编程的艺术》一书中一个经典的实现线程间通信的案例&#xff0c;主要是使用wait() 和 notifyAll() 方法来实现的。 这段代码的作用是通过 wait() 和 notifyAll() 方法实现线程间的等待和通知机制。具体来说&#xff0c;代码中创建了两个线程&…

论文阅读-Multiple Targets Directed Greybox Fuzzing (Hongliang Liang,2024)

标题: Multiple Targets Directed Greybox Fuzzing (Hongliang Liang,2024) 作者: Hongliang Liang, Xinglin Yu, Xianglin Cheng, Jie Liu, Jin Li 期刊: IEEE Transactions on Dependable and Secure Computing 研究问题: 发现局限性&#xff1a;之前的定向灰盒测试在有…

webAssembly学习及使用rust

学习理解 webAssembly 概念知识&#xff0c;使用 API 进行 web 前端开发。 概念 是一种运行在现代网络浏览器中的新型代码&#xff0c;并且提供新的性能特性和效果。它有一种紧凑的二进制格式&#xff0c;使其能够以接近原生性能的速度运行。C/C、 C#、Rust等语言可以编译为 …

ruby 配置代理 ip(核心逻辑)

在 Ruby 中配置代理 IP&#xff0c;可以通过设置 Net::HTTP 类的 Proxy 属性来实现。以下是一个示例&#xff1a; require net/http// 获取代理Ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg proxy_address 代理IP:端口 uri URI(http://www.example.com)Net:…

【React】Sigma.js框架网络图-入门篇

一、介绍 Sigma.js是一个专门用于图形绘制的JavaScript库。 它使在Web页面上发布网络变得容易&#xff0c;并允许开发人员将网络探索集成到丰富的Web应用程序中。 Sigma.js提供了许多内置功能&#xff0c;例如Canvas和WebGL渲染器或鼠标和触摸支持&#xff0c;以使用户在网页上…

MATLAB R2024a:重塑商业数学软件的未来

在数字化浪潮席卷全球的今天&#xff0c;商业数学软件已经成为企业、研究机构乃至个人不可或缺的工具。而在这其中&#xff0c;MATLAB R2024a以其卓越的性能和广泛的应用领域&#xff0c;正逐步成为商业数学软件的新标杆。 MATLAB R2024a不仅继承了前代版本的优秀基因&#xf…

Golang 采集爬虫如何配置代理 IP

在 Golang 中配置代理 IP&#xff0c;可以通过设置 http.Transport 的 Proxy 属性来实现&#xff1a; 下述代码中的 代理IP 和 端口 替换为实际的代理服务器地址和端口&#xff0c;然后运行该程序即可通过代理服务器访问对应网站。 package mainimport ("fmt""…

超详细的Maven安装与使用还有内容讲解

文章目录 作用简介模型仓库 安装配置IDEA配置Maven坐标概念主要组成 IDEA创建Maven项目基本使用常用命令生命周期使用坐标导入jar包 注意事项清理maven仓库更新索引依赖 作用 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化…

MATLAB实现禁忌搜索算法优化柔性车间调度fjsp

禁忌搜索算法的流程可以归纳为以下几个步骤&#xff1a; 初始化&#xff1a; 利用贪婪算法或其他局部搜索算法生成一个初始解。清空禁忌表。设置禁忌长度&#xff08;即禁忌表中禁止操作的期限&#xff09;。邻域搜索产生候选解&#xff1a; 通过特定的搜索算子&#xff08;如…

AWS账号注册以及Claude 3 模型使用教程!

哈喽哈喽大家好呀&#xff0c;伙伴们&#xff01;你听说了吗&#xff1f;最近AWS托管了大热模型&#xff1a;Claude 3 Opus&#xff01;想要一探究竟吗&#xff1f;那就赶紧来注册AWS账号吧&#xff01;别担心&#xff0c;现在注册还免费呢&#xff01;而且在AWS上还有更多的大…

【北京迅为】《iTOP-3588开发板系统编程手册》-第10章 存储映射 I/O

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

Spark-Scala语言实战(17)

我带着大家一起来到Linux集群环境下&#xff0c;学习我们的spark。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&#xff08;16&#x…

基于Springboot的社区帮扶对象管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的社区帮扶对象管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

微信小程序日期增加时间完成订单失效倒计时(有效果图)

效果图 .wxml <view class"TimeSeond">{{second}}</view>.js Page({data: {tiem_one:,second:,//倒计时deadline:,},onLoad(){this.countdown();},countdown(){let timestamp Date.parse(new Date()) / 1000;//当前时间戳let time this.addtime(2024…

数据结构- 顺序表-单链表-双链表 --【求个关注!】

文章目录 一 顺序表代码&#xff1a; 二 链表单链表双向链表 一 顺序表 顺序表是线性表的一种 所谓线性表指一串数据的组织存储在逻辑上是线性的&#xff0c;而在物理上不一定是线性的 顺序表的底层实现是数组&#xff0c;其由一群数据类型相同的元素组成&#xff0c;其在逻辑…
最新文章