工厂设计模式

news2025/7/16 3:07:49

介绍

Java工厂设计模式主要分为三种:

  1. 简单工厂模式(Simple Factory Pattern):使用一个工厂类来封装对象创建的过程,客户端只需要通过传递不同的参数来获取不同的产品对象,从而避免了客户端直接创建产品对象的操作
  2. 工厂方法模式(Factory Method Pattern):将工厂类抽象出来,每个具体产品类对应一个具体工厂类,工厂类通过多态性来创建对应的产品对象,客户端只需要知道工厂接口及其实现类即可,可以根据需求动态切换工厂实现,扩展性更好.
  3. 抽象工厂模式(Abstract Factory Pattern):在工厂方法模式的基础上,将工厂类再进行一次抽象,将多个工厂接口放到一个工厂接口中,每个具体产品对应一个具体工厂类,通过多态性来创建对应的产品对象,具有更好的扩展性和更高的抽象程度,但是也增加了系统复杂度

简单工厂模式

首先先定义一个抽象产品类:

package com.fanqiechaodan.factory.simple.product;

/**
 * @author fanqiechaodan
 * @Classname Product
 * @Description 抽象产品类
 * @Date 2023/3/8 18:39
 */
public abstract class Product {

    public abstract void use();
}

然后定义具体产品类

public class ProductA extends Product{

    @Override
    public void use() {
        System.out.println("使用具体产品类A...");
    }
}

public class ProductB extends Product{

    @Override
    public void use() {
        System.out.println("使用具体产品类B...");
    }
}

public class ProductC extends Product{
    
    @Override
    public void use() {
        System.out.println("使用具体产品类C...");
    }
}

接下来定义工厂类,用于创建不同的产品

package com.fanqiechaodan.factory.simple.factory;

import com.fanqiechaodan.factory.simple.product.Product;
import com.fanqiechaodan.factory.simple.product.ProductA;
import com.fanqiechaodan.factory.simple.product.ProductB;
import com.fanqiechaodan.factory.simple.product.ProductC;

/**
 * @author fanqiechaodan
 * @Classname SimpleFactory
 * @Description 工厂类
 * @Date 2023/3/8 18:42
 */
public class SimpleFactory {

    public static Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ProductA();
            case "B":
                return new ProductB();
            case "C":
                return new ProductC();
            default:
                throw new RuntimeException("不支持的产品类型:" + type);
        }

    }
}

测试:

package com.fanqiechaodan.factory.simple;

import com.fanqiechaodan.factory.simple.factory.SimpleFactory;
import com.fanqiechaodan.factory.simple.product.Product;

/**
 * @author fanqiechaodan
 * @Classname Demo
 * @Description 简单工厂模式
 * @Date 2023/3/8 18:46
 */
public class Demo {

    public static void main(String[] args) {
        Product productA = SimpleFactory.createProduct("A");
        productA.use();

        Product productB = SimpleFactory.createProduct("B");
        productB.use();

        Product productC = SimpleFactory.createProduct("C");
        productC.use();

        Product productD = SimpleFactory.createProduct("D");
        productD.use();
    }
}

在这里插入图片描述

工厂方法模式

首先定义一个接口表示产品

package com.fanqiechaodan.factory.method.product;

/**
 * @author fanqiechaodan
 * @Classname Product
 * @Description 产品接口
 * @Date 2023/3/8 18:58
 */
public interface Product {

    void use();
}

其次定义两个具体的产品实现类

public class ProductA implements Product{

    @Override
    public void use() {
        System.out.println("使用具体产品A...");
    }
}

public class ProductB implements Product{

    @Override
    public void use() {
        System.out.println("使用具体产品B...");
    }
}

然后定义一个工厂接口用于创建产品

package com.fanqiechaodan.factory.method.factory;

import com.fanqiechaodan.factory.method.product.Product;

/**
 * @author fanqiechaodan
 * @Classname Factory
 * @Description 工厂接口
 * @Date 2023/3/8 19:00
 */
public interface Factory {

    Product createProduct();

}

接下来,定义两个具体的工厂实现类,分别用于创建不同的产品

public class FactoryA implements Factory{


    @Override
    public Product createProduct() {
        return new ProductA();
    }
}

public class FactoryB implements Factory{

    @Override
    public Product createProduct() {
        return new ProductB();
    }
}

测试

package com.fanqiechaodan.factory.method.factory;

import com.fanqiechaodan.factory.method.product.Product;
import com.fanqiechaodan.factory.method.product.ProductB;

/**
 * @author fanqiechaodan
 * @Classname FactoryB
 * @Description 工厂实现类B
 * @Date 2023/3/8 19:02
 */
public class FactoryB implements Factory{

    @Override
    public Product createProduct() {
        return new ProductB();
    }
}

在这里插入图片描述

抽象工厂模式

首先定义抽象产品

public interface ProductA {

    void doSomething();
}

public interface ProductB {

    void doSomething();
}

其次定义具体产品

public class ProductA1 implements ProductA{

    @Override
    public void doSomething() {
        System.out.println("ProductA1 doSomething ...");
    }
}

public class ProductA2 implements ProductA{

    @Override
    public void doSomething() {
        System.out.println("ProductA2 doSomething ...");
    }
}

public class ProductB1 implements ProductB{

    @Override
    public void doSomething() {
        System.out.println("ProductB1 doSomething ...");
    }
}

public class ProductB2 implements ProductB{

    @Override
    public void doSomething() {
        System.out.println("ProductB2 doSomething ...");
    }
}

然后定义抽象工厂

package com.fanqiechaodan.factory.abstractfactory.factory;

import com.fanqiechaodan.factory.abstractfactory.product.ProductA;
import com.fanqiechaodan.factory.abstractfactory.product.ProductB;

/**
 * @author fanqiechaodan
 * @Classname AbstractFactory
 * @Description 抽象工厂
 * @Date 2023/3/8 19:08
 */
public interface AbstractFactory {

    ProductA createProductA();

    ProductB createProductB();
}

接下来定义具体工厂

public class Factory1 implements AbstractFactory{

    @Override
    public ProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB1();
    }
}

public class Factory2 implements AbstractFactory{

    @Override
    public ProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB2();
    }
}

测试

package com.fanqiechaodan.factory.abstractfactory;

import com.fanqiechaodan.factory.abstractfactory.factory.AbstractFactory;
import com.fanqiechaodan.factory.abstractfactory.factory.Factory1;
import com.fanqiechaodan.factory.abstractfactory.factory.Factory2;
import com.fanqiechaodan.factory.abstractfactory.product.ProductA;
import com.fanqiechaodan.factory.abstractfactory.product.ProductB;

/**
 * @author fanqiechaodan
 * @Classname Demo
 * @Description 抽象工厂模式
 * @Date 2023/3/8 19:40
 */
public class Demo {

    public static void main(String[] args) {
        // 使用具体工厂1创建产品A和产品B
        AbstractFactory factory1 = new Factory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.doSomething();
        productB1.doSomething();

        // 使用具体工厂2创建产品A和产品B
        AbstractFactory factory2 = new Factory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.doSomething();
        productB2.doSomething();
    }
}

在这里插入图片描述

总结

  1. 简单工厂模式

    优点:

    • 简单易用,客户端只需要知道工厂类和产品类即可
    • 工厂类负责创建对象,客户端无需知道具体得实现细节
    • 可以根据参数动态创建对象

    缺点:

    • 工厂类负责创建所有得产品对象,当产品类型过多时,工厂类会变得十分臃肿
    • 添加新产品需要修改工厂类的代码,违反了开闭原则
  2. 工厂方法模式

    优点:

    • 将每个产品类型的创建部分分散到具体的工厂类中,避免了简单工厂模式中工厂类臃肿的问题
    • 添加新产品只需要添加具体工厂类即可,符合开闭原则

    缺点:

    • 客户端需要知道所有具体工厂类,使用起来不够灵活
    • 每个产品类型都需要对应一个具体的工厂类,增加了系统类的个数,增加了系统的复杂度
  3. 抽象工厂模式

    优点:

    • 可以创建一组相关的产品对象,确保这些对象之间的兼容性
    • 隐藏了产品对象的具体实现,客户端只需要知道抽象工厂和抽象产品即可
    • 可以通过替换具体工厂来实现不同的产品组合,提高了系统的灵活性

    缺点;

    • 增加了系统的抽象性和复杂度,需要定义多个抽象工厂接口和多个具体工厂类
    • 不容易支持新种类的产品,需要添加新的产品工厂接口和具体工厂类

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

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

相关文章

fastjson 返回 $ref 数据

文章目录问题描述:1、重复引用:2、循环引用:原因分析:1、重复引用:2、循环引用:反序列化:1、开启引用检测:2、关闭引用检测:小结:问题描述: 问题…

小樽C++ 单章⑨ 文件

目录 1.文件类型变量的定义与引用 1.1 文件的读写 1.2 fopen()版 (C专用) 1.3 文件输入输出流 (C专用) 文件有两种保存方式:二进制文件、文本文件。例如存121这个数字。 二进制存储效率高,但是对我们不友好,对每个值都要变成二进制太难啦…

uniapp实现自定义相机

自定义相机起因由于最近用uniapp调用原生相机容易出现闪退问题,找了很多教程又是压缩图片又是优化代码,我表示并没有太大作用!!实现自定义相机使用效果图拓展实现多种自定义相机水印相机身份证相机人像相机起因 由于最近用uniapp调用原生相机容易出现闪退…

MindAR的网页端WebAR图片识别功能的图片目标编译器中文离线版本功能(含源码)

前言 之前制作了基于MindAR实现的网页端WebAR图片识别叠加动作模型追踪功能的demo,使用了在线的图像目标编译器对识别图进行了编译,并实现了自制的WebAR效果,大致效果如下: 但是在线的编译器在操作中也不是很方便,我…

207. 课程表

207. 课程表https://leetcode.cn/problems/course-schedule/ 难度中等1526 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] [a…

One-YOLOv5 v1.2.0 Released(支持分类,检测,实例分割)

0x0. 引言0x1. 快速开始0x2. 在COCO上的精度表现 yolov5s-defaultyolov5s-seg 0x3. 在COCO上的单GPU性能表现特性 & bug 修复 特性用户反馈的bug 下个版本的展望附件常用预训练模型下载列表 0x0. 引言 🌟 v1.2.0同步了ultralytics yolov5的上游分支v7.0 &…

Python+ChatGPT制作一个AI实用百宝箱

目录一、注册OpenAI二、搭建网站及其框架三、AI聊天机器人四、AI绘画机器人ChatGPT 最近在互联网掀起了一阵热潮,其高度智能化的功能能够给我们现实生活带来诸多的便利,可以帮助你写文章、写报告、写周报、做表格、做策划甚至还会写代码。只要与文字相关…

The Sandbox 中的独特体验——《奥米加》

在过去几年间,The Sandbox 游戏变得越来越受欢迎。因为我们为玩家提供了在虚拟世界中探索、创造和游戏的自由,没有线性游戏的限制。DeQuest 工作室创作的《奥米加》也正是如此,绝对是一个前所未有的体验! 先了解一下《奥米加》的故…

代码审计之旅之百家CMS

前言 之前审计的CMS大多是利用工具,即Seay昆仑镜联动扫描出漏洞点,而后进行审计。感觉自己的能力仍与零无异,因此本次审计CMS绝大多数使用手动探测,即通过搜索危险函数的方式进行漏洞寻找,以此来提升审计能力&#xf…

网易云信 Crash 异常治理实践 | 智企技术委员会技术专题系列

前言Crash(造成用户无法使用客户端所承载的服务)作为客户端稳定治理的最主要问题之一。云信作为国内业界领先的 RTC/IM PaaS 服务商,对于客户端 SDK(PaaS 服务商对外服务的主要载体)的 Crash 治理再重视也不为过。关于…

【编程基础之Python】12、Python中的语句

【编程基础之Python】12、Python中的语句Python中的语句赋值语句条件语句循环语句for循环while循环continue语句break语句continue与break的区别函数语句pass语句异常处理语句结论Python中的语句 Python是一种高级编程语言,具有简单易学的语法,适用于各…

JAVA架构与开发(JAVA架构是需要考虑的几个问题)

在企业中JAVA架构师主要负责企业项目技术架构,企业技术战略制定,技术框架搭建,技术培训和技术攻坚的工作。 在JAVA领域,比较多的都是web项目。用于解决企业的数字化转型。对于JAVA架构师而言,平时对项目的架构主要考虑…

yolov7改进系列

1. YOLOv7改进结构系列: 最新结合用于小目标的新CNN卷积构建 (71条消息) YOLOv7改进结构系列: 最新结合用于小目标的新CNN卷积构建块_芒果汁没有芒果的博客-CSDN博客 一、SPD论文理论部分 卷积神经网络 (CNN) 在许多计算机视觉任务(例如图像…

CMU15-445 Project.3总结

在线测试 Project #3 - Query Execution 以下是Project #3的网址,2022FALL的Project #3是实现一个查询执行,实现一系列算子,用于实现数据库内的SQL计算。项目中的 Query Execution 主要分为三个任务: Access Method Executors…

九龙证券|整合大年 钢企迎来盈亏平衡新周期

经历上一年的“至暗时间”后,2023年的钢铁工业正从盈亏平衡的新窗口探出面来。证券时报记者从多家钢企和钢贸商处确认,本年以来钢材价格试探性上涨频现,量价、开工率、库存等指标都呈现向好趋向。 如果说供应侧结构性变革是推动上一轮钢铁工业…

HTML 简介

文章目录HTML 简介实例解析什么是HTML?HTML 标签HTML 元素Web 浏览器HTML 网页结构HTML版本<!DOCTYPE> 声明通用声明HTML5HTML 4.01XHTML 1.0中文编码HTML 简介 HTML 实例 <!DOCTYPE html> <html><head><meta charset"utf-8"><ti…

Spring——数据源对象管理和Spring加载properties文件

前面一直都是在管理自己内部创建的对象&#xff0c;这个是管理外部的对象。 这里先使用阿里巴巴的druid来演示。需要在pom.xml中添加如下的依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1…

Leetcode.2416 字符串的前缀分数和

题目链接 Leetcode.2416 字符串的前缀分数和 Rating &#xff1a; 1725 题目描述 给你一个长度为 n的数组 words&#xff0c;该数组由 非空 字符串组成。 定义字符串 word的 分数 等于以 word作为 前缀 的 words[i]的数目。 例如&#xff0c;如果 words ["a", &q…

C++STL详解(五)——list的介绍与使用

文章目录list的介绍list的使用list的定义方法list迭代器失效问题list插入和删除inserteraselist迭代器的使用begin&#xff0c;end 和 rbegin&#xff0c;rendlist元素访问front 和 backlist容量控制与数据清理resizeclearlist操作函数spliceremove 和 remove_ifuniquemergerev…

安卓开发之动态设置网络访问地址

之前开发程序联测测接口的时候&#xff0c;因为要和不同的后台人员调接口&#xff0c;所以经常要先把程序里的ip地址改成后台人员给我的。每次都要先修改ip地址&#xff0c;之后编译运行一下&#xff0c;才能测试。但要是换了个后台人员&#xff0c;或者同时和2个后台人员测接口…