设计模式——三大工厂模式

news2024/12/23 15:23:15

工厂模式

简单工厂模式(静态工厂模式)

介绍:

1、简单工厂模式是属于创建型模式,是工厂模式的一种,**简单工厂模式是由一个工厂对象决定创建出哪种产品的实例**。是工厂模式中最简单使用的模式
2、简单工厂模式:定义了一个创建对象的类,由这个类封装实例化对象的行为(代码)
3、在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

public interface Shape {
    void draw();
}
​
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制一个圆形");
    }
}
​
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制一个矩形");
    }
}
​
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制一个正方形");
    }
}
​
​
public class ShapeFactory {
    public static Shape createShape(String type) {
        if (type.equalsIgnoreCase("circle")) {
            return new Circle();
        } else if (type.equalsIgnoreCase("rectangle")) {
            return new Rectangle();
        } else if (type.equalsIgnoreCase("square")) {
            return new Square();
        }
        return null;
    }
}
​
​
public class Main {
    public static void main(String[] args) {
        Shape circle = ShapeFactory.createShape("circle");
        circle.draw();  // 输出:绘制一个圆形
​
        Shape rectangle = ShapeFactory.createShape("rectangle");
        rectangle.draw();  // 输出:绘制一个矩形
​
        Shape square = ShapeFactory.createShape("square");
        square.draw();  // 输出:绘制一个正方形
    }
}
总结:
优点:
​
1、简单工厂模式实现了对象创建和对象使用的分离,客户端只需知道产品的类型,无需关心产品的创建细节。
2、可以通过工厂方法来集中控制对象的创建,便于统一管理和维护。
3、客户端可以直接通过工厂类来创建对象,简化了客户端代码,提高了代码的可读性和可维护性。
4、简单工厂模式实现了依赖倒置原则,客户端只需要依赖工厂类,而不需要依赖具体的产品类,降低了耦合
​
​
缺点:
​
1、当需要新增产品时,需要修改工厂类的代码,违反了开闭原则。
2、工厂类的职责较重,包括对象的创建和选择逻辑,违反了单一职责原则。
3、对象的创建过程集中在一个工厂类中,如果系统中的产品过多或产品创建过程复杂,会导致工厂类臃肿,不利于扩展和维护。
4、简单工厂模式会导致客户端与工厂类之间的耦合度增加,一旦工厂类出现问题,客户端可能也会受到影响。
​
​
总的来说,简单工厂模式适用于对象较少且变化不频繁的场景,但在面对频繁变化的产品类型或产品创建过程复杂的情况下,不太适合使用简单工厂模式。

工厂方法模式

介绍

定义了一个创建对象的抽象方法,由子类决定要实例化的累。工厂方法模式将对象的实例化放到子类。(子类进行生产对象)
// 抽象产品类
interface Product {
    void operation();
}
​
// 具体产品类A
class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductA operation");
    }
}
​
// 具体产品类B
class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductB operation");
    }
}
​
// 工厂接口
interface Factory {
    Product createProduct();
}
​
// 具体工厂A
class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}
​
// 具体工厂B
class ConcreteFactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}
​
// 客户端代码
public class Client {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.operation();
​
        Factory factoryB = new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.operation();
    }
}
优点: 1、松耦合:工厂方法模式将客户端代码与具体产品类解耦,客户端不需要知道具体产品的类名,只需要知道产品的接口或抽象类即可。这使得系统更容易维护和扩展,因为新增产品时只需添加新的具体产品类和对应的工厂类,而不需要修改现有的客户端代码。 ​ 2、可扩展性:由于每个具体产品都有对应的具体工厂,可以轻松地添加新的具体产品类和对应的工厂类,而不会影响现有的代码结构。这使得系统具有很好的可扩展性,符合开闭原则。 ​ 3、封装变化:工厂方法模式将对象的创建过程封装到具体的工厂类中,客户端无需关心对象的创建细节,只需通过工厂来获取对象。这样,如果对象的创建过程发生变化,只需修改对应的工厂类,而不会影响客户端代码。 ​ 缺点: 1、类的数量增加:工厂方法模式会导致系统中类的数量增加,因为每个具体产品都需要对应一个具体工厂。如果产品种类很多,会导致类的数量剧增,增加了系统的复杂度。 ​ 2、增加了系统的抽象性和理解难度:引入了抽象工厂和具体工厂的概念,增加了系统的抽象性,使得系统的理解和学习成本增加。 ​ 3、一定程度上增加了开发的复杂度:相对于简单的直接实例化对象来说,工厂方法模式引入了额外的抽象层,增加了开发的复杂度,尤其是对于简单的场景来说可能会显得过于繁琐。 ​ 工厂方法模式的优点包括松耦合、可扩展性和封装变化。它将客户端代码与具体产品类解耦,使系统更易于维护和扩展。缺点包括增加类的数量、增加系统的抽象性和理解难度,以及在一定程度上增加了开发的复杂度。在设计时需要权衡利弊,根据具体情况选择是否使用工厂方法模式

抽象工厂模式

介绍:

1、抽象工厂模式:它提供了一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。
-》 说明抽象工厂模式允许客户端使用抽象的接口来创建相关的产品对象,并且不需要知道具体实现
​
2、将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。我们可以根据创建类型和使用对应的工厂子类,将单个的简单工厂类变成工厂家族,利于代码的维护和扩展

这是一个类图:

抽象工厂就是有一个总的抽象工厂类,然后有子类去实现这个抽象工厂来实现它,并且为之实现生产产品的方法

定义抽象工厂 PizzaFactory 和抽象产品接口 Pizza 以及原料接口 PizzaIngredient:

// 抽象工厂
interface PizzaFactory {
    Pizza createPizza();
    PizzaIngredient createIngredient();
}
​
// 抽象产品 - 披萨
interface Pizza {
    void prepare();
    void bake();
    void cut();
    void box();
}
​
// 抽象产品 - 原料
interface PizzaIngredient {
    String getIngredient();
}
​
这里是实现具体的工厂类和产品类:

// 具体工厂类 - 纽约风味披萨工厂
class NYPizzaFactory implements PizzaFactory {
    @Override
    public Pizza createPizza() {
        return new NYStylePizza();
    }
​
    @Override
    public PizzaIngredient createIngredient() {
        return new NYStyleIngredient();
    }
}
​
// 具体工厂类 - 芝加哥风味披萨工厂
class ChicagoPizzaFactory implements PizzaFactory {
    @Override
    public Pizza createPizza() {
        return new ChicagoStylePizza();
    }
​
    @Override
    public PizzaIngredient createIngredient() {
        return new ChicagoStyleIngredient();
    }
}
​
// 具体产品类 - 纽约风味披萨
class NYStylePizza implements Pizza {
    // 省略具体实现
}
​
// 具体产品类 - 芝加哥风味披萨
class ChicagoStylePizza implements Pizza {
    // 省略具体实现
}
​
// 具体产品类 - 纽约风味原料
class NYStyleIngredient implements PizzaIngredient {
    @Override
    public String getIngredient() {
        return "NY style ingredient";
    }
}
​
// 具体产品类 - 芝加哥风味原料
class ChicagoStyleIngredient implements PizzaIngredient {
    @Override
    public String getIngredient() {
        return "Chicago style ingredient";
    }
}
​
// 客户端代码
public class PizzaStore {
    private PizzaFactory factory;
​
    public PizzaStore(PizzaFactory factory) {
        this.factory = factory;
    }
​
    public Pizza orderPizza() {
        Pizza pizza = factory.createPizza();
        PizzaIngredient ingredient = factory.createIngredient();
        System.out.println("Preparing " + pizza.getClass().getSimpleName() + " with " + ingredient.getIngredient());
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
​
    public static void main(String[] args) {
        PizzaStore nyStore = new PizzaStore(new NYPizzaFactory());
        nyStore.orderPizza();
​
        PizzaStore chicagoStore = new PizzaStore(new ChicagoPizzaFactory());
        chicagoStore.orderPizza();
    }
}

抽象工厂模式是一种创建型设计模式,它提供了一种封装一组相关对象创建的方式。
​
优点:
抽象工厂模式通过解耦具体类的创建与客户端代码,确保产品系列相互匹配,并容易交换不同产品系列
​
​
缺点:
​
增加新的产品族或产品等级结构可能导致抽象工厂接口和具体工厂类的修改,以及需要修改所有客户端代码。

小结

工厂模式在JDK-Calendar应用的源码:使用到了简单工厂模式

1、工厂模式的目的:

将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。

2、三种工厂模式

- 简单工厂模式:由一个工厂类根据客户端请求创建产品,适用于产品种类较少且变化不频繁的情况。
​
  
​
- 工厂方法模式:定义创建对象接口,延迟具体创建到子类实现,允许系统引入新产品而不修改客户端代码。
​
  
​
- 抽象工厂模式:提供接口创建相关对象,通过具体工厂创建产品族,适用于创建相互关联或依赖对象的情况。

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

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

相关文章

ONLYOFFICE8.0——赋能办公

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-xdAoM2pHRmDFP0tF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

挑战30天学完Python:Day18 正则表达式

📘 Day 18 🎉 本系列为Python基础学习,原稿来源于 30-Days-Of-Python 英文项目,大奇主要是对其本地化翻译、逐条验证和补充,想通过30天完成正儿八经的系统化实践。此系列适合零基础同学,或仅了解Python一点…

Python 在Word中创建表格并填入数据、图片

在Word中,表格是一个强大的工具,它可以帮助你更好地组织、呈现和分析信息。本文将介绍如何使用Python在Word中创建表格并填入数据、图片,以及设置表格样式等。 Python Word库: 要使用Python在Word中创建或操作表格,需…

24款奔驰C260L升级C63包围 渣男的外观

今天店里来了一台24款奔驰C260L 一提车就过来升级 我们公司还有包上牌服务 车主说 升级完包围 帮忙安排一下 原车的包围 没有那么霸气 特别是后杠 光溜溜的 升级后 四出尾喉 尾翼 直接牌面就起来了,星骏汇小许Xjh15863

【统计分析数学模型】判别分析(四):机器学习分类算法

【统计分析数学模型】判别分析(四):机器学习分类算法 一、机器学习分类算法1. 交叉验证方法2. 案例数据集3. 数据标准化 二、决策树模型1. 基本原理2. 计算步骤3. R语言实现 三、K最邻近分类1. 基本原理2. K值的选择3. R语言实现 四、支持向量…

图像压缩感知的MATLAB实现(OMP)

前面实现了 压缩感知的图像仿真(MATLAB源代码) 效果还不错,缺点是速度慢如牛。 下面我们采用OMP对其进行优化,提升速度。具体代码如下: 仿真 构建了一个MATLAB文件,所有代码都在一个源文件里面&#xf…

MySQL——基础内容

目录 第01章_数据库概述 关系型数据库(RDBMS)——表、关系模型 非关系型数据库(非RDBMS) 表、记录、字段 表的关联关系 一对一关联 一对多关系 多对多 自我引用 第02章_MySQL环境搭建 登录命令 常用命令 show databases; create database use 数据库名 show tables 第03章…

2023最新简绘AI开源版支持MJ绘画,AI问答

应用介绍 本文来自:2023最新简绘AI开源版支持MJ绘画,AI问答 - 源码1688 简介: 简绘AI开源版,从闲鱼上买的,搭建教程如下 测试环境:NginxPHP7.4MySQL5.6 图片:

CentOS 中 RSYNC 同步分发脚本一键部署

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

ChatGpt的初步认知(认知搬运工)

前言 ChatGpt火了有一段时间了,对各行各业也有了一定的渗透,当然发展过程中也做了一些安全约束,今天主要是来跟大家分享下关于chatGpt的初步认知。 一、chatGpt是什么? ChatGPT,全称聊天生成预训练转换器(英…

如何利用AI产品写作高质量SEO文章

在搜索引擎优化(SEO)的过程中,我们的目标非常明确,即增加网站的流量并实现有效的转化。那么,如何才能吸引更多的用户访问网站呢?这时候,文章就成为了一个非常好的工具。用户可以通过阅读文章来了…

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x Projectpom.xmlOpenAPIConfigFileUploadControllerapplication.yaml Project pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://…

【科普知识】什么是电机的开环和闭环

电机是现代工业和生活中不可或缺的一部分&#xff0c;无论是电动工具、电动汽车还是工业机器人&#xff0c;都离不开电机的驱动。电机的控制系统根据有无反馈信号可以分为开环和闭环两种类型&#xff0c;这两种系统各有其特点和应用场景。 01.开环控制系统 开环控制系统是电机控…

AP引擎助力加速生产SQL运行

Rapid存储引擎简介 从GreatSQL 8.0.32-25版本开始&#xff0c;新增Rapid存储引擎&#xff0c;该引擎使得GreatSQL能满足联机分析&#xff08;OLAP&#xff09;查询请求。 Rapid引擎采用插件&#xff08;Plugin&#xff09;方式嵌入GreatSQL中&#xff0c;可以在线动态安装或卸…

(九)springmvc+mybatis+dubbo+zookeeper分布式架构 整合 - maven构建ant-framework核心代码Base封装

今天重点讲解的是ant-framework核心代码Base封装过程。 因为涉及到springmvc、mybatis的集成&#xff0c;为了使项目编码更简洁易用&#xff0c;这边将基础的BASE进行封装&#xff0c;其中包括&#xff1a;BaseBean、BaseDao、BaseService、CRUD的基础封装、分页组件的封装、m…

OSCP靶场--Nickel

OSCP靶场–Nickel 考点(1.POST方法请求信息 2.ftp&#xff0c;ssh密码复用 3.pdf文件密码爆破) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.237.99 -sV -sC -p- --min-rate 5000 Starting Nmap 7.92 ( https://nmap.org ) at 2024-02-22 04:06 EST Nm…

22款奔驰C260L升级小柏林音响 无损音质效果

奔驰新款C级号称奔驰轿车的小“S”&#xff0c;在配置方面上肯定也不能低的&#xff0c;提了一台低配的车型&#xff0c;通过后期升级加装件配置提升更高档次&#xff0c;打造独一无二的奔驰C级&#xff0c;此次来安排一套小柏林之声音响&#xff0c;效果怎么样&#xff0c;我们…

maven3旧版本的下载地址(含新版本)

因为现有的3.8版本与IDEA不兼容&#xff0c;我需要下载3.6版本&#xff0c;但是官网的位置非常隐蔽&#xff0c;找了很多资料才看到。故记录一下。 第一步 进入网址&#xff0c;选择需要的版本 Index of /dist/maven/maven-3 第二步 选择binaries 第三步 选择zip文件下载就可…

Nacos配置中心实战

目录 配置中心 什么是Nacos配置中心&#xff1f; SpringCloud整合Nacos配置中心 nacos server配置中心中准备配置数据 微服务接入配置中心 Config相关配置 RefreshScope实现动态感知 配置中心 在微服务架构中&#xff0c;当系统从一个单体应用&#xff0c;被拆分成分布式…

Qt应用-音乐播放器实例

本文讲解Qt音乐播放器应用实例。 实现主要功能 声音播放、暂停,拖动控制、声音大小调节; 播放列表控制; 歌词显示; 界面设计 pro文件中添加 # 播放媒体 QT += multimedia 头文件 #ifndef FRMMUSICPLAYER_H #define FRMMUSICPLAYER_H#include <QWidget> #include…