首页 > 其他分享 >【设计模式】工厂模式(创建型)⭐⭐⭐

【设计模式】工厂模式(创建型)⭐⭐⭐

时间:2024-06-05 17:30:13浏览次数:24  
标签:Spring 模式 工厂 抽象 创建 设计模式 public

文章目录

1.概念

1.1 什么是工厂模式

工厂模式属于创建型模式。它的主要目的是提供一个创建对象的接口,而不直接实例化对象。这样可以将对象的创建和使用分离,降低系统的耦合度,提高系统的灵活性和可扩展性。

1.2 优点与缺点

优点:
1.降低了系统中对象的耦合度,提高了系统的灵活性。
2.增加了系统的可扩展性,当增加新的产品时,只需扩展一个工厂类即可。
3.隔离了具体产品的创建,使得代码符合单一职责原则。
缺点:
1.增加了系统的复杂度,因为引入了新的工厂类层次。
2.如果产品等级结构过于复杂,那么工厂方法模式的类层次也会相当复杂。

2.实现方式

2.1 简单工厂模式(Simple Factory)

① 定义产品接口或抽象类

public interface Product {
    void operate();
}

② 实现具体产品类:接着,我们创建具体的产品类,它们实现了产品接口或继承了抽象类。

public class ConcreteProductA implements Product {
    @Override
    public void operate() {
        System.out.println("ConcreteProductA operates.");
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void operate() {
        System.out.println("ConcreteProductB operates.");
    }
}

③ 创建工厂类:然后,我们创建一个工厂类,它提供一个静态方法来创建产品对象。工厂方法根据传入的参数来决定创建哪个具体产品类的实例。

public class SimpleFactory {
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        }
        return null;
    }
}

④ 客户端代码:最后,客户端代码通过调用工厂类的静态方法来获取产品实例,而不是直接创建产品对象。

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

        productA.operate();
        productB.operate();
    }
}

这种实现方式使得客户端代码与具体产品类的实现解耦,提高了系统的灵活性和可扩展性。如果需要增加新的产品类,只需要扩展新的具体产品类,并在工厂类中增加相应的创建逻辑,而不需要修改客户端代码。

2.2 简单工厂模式缺点

违反开闭原则:简单工厂模式的工厂方法集中了所有产品的创建逻辑。当需要增加新的产品时,必须修改工厂方法来实现新的逻辑,这违反了开闭原则(软件实体应该对扩展开放,对修改关闭)。
工厂方法单一职责原则:随着产品种类增加,工厂方法会变得越来越复杂,包含大量的条件分支语句。这使得工厂类承担了过多的责任,违反了单一职责原则(一个类应该只有一个引起它变化的原因)。
扩展困难:由于工厂类集中了所有产品的创建逻辑,当产品种类很多时,工厂类会变得非常庞大,难以维护和扩展。
依赖集中:客户端代码依赖于工厂类,如果工厂类发生变化,可能会影响到客户端代码。
不利于产品类的解耦:虽然简单工厂模式将客户端的创建逻辑和产品类的实现解耦,但是产品类和工厂类之间的耦合度仍然较高,因为工厂类需要知道所有产品类的具体实现。
不利于反射和依赖注入:由于工厂类内部硬编码了产品类的创建逻辑,这使得在运行时难以通过反射或依赖注入的方式来动态地创建和替换产品对象。

2.3 抽象工厂模式(Abstract Factory Pattern)

① 定义抽象工厂接口:声明了一组用于创建抽象产品对象的方法。

public interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

② 实现具体工厂类:实现了抽象工厂接口,每个具体工厂都负责创建自己产品系列中的对象。

public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

public class ConcreteFactory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

③ 定义抽象产品接口:声明了产品的公共接口。

public interface AbstractProductA {
    void usefulFunctionA();
}

public interface AbstractProductB {
    void usefulFunctionB();
}

④ 实现具体产品类:实现了抽象产品接口,每个具体产品都属于一个产品系列。

public class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void usefulFunctionA() {
        // 具体实现
    }
}

public class ConcreteProductA2 implements AbstractProductA {
    @Override
    public void usefulFunctionA() {
        // 具体实现
    }
}

public class ConcreteProductB1 implements AbstractProductB {
    @Override
    public void usefulFunctionB() {
        // 具体实现
    }
}

public class ConcreteProductB2 implements AbstractProductB {
    @Override
    public void usefulFunctionB() {
        // 具体实现
    }
}

⑤ 客户端代码:客户端通过抽象工厂接口来创建产品,而不需要关心具体工厂和产品的实现细节。

public class Client {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.usefulFunctionA();
        productB1.usefulFunctionB();

        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.usefulFunctionA();
        productB2.usefulFunctionB();
    }
}

3. Java 哪些地方用到了工厂模式

Java AWT(Abstract Window Toolkit):AWT中的 Button, TextField, Label 等组件在不同的操作系统上会有不同的外观和行为。AWT使用抽象工厂模式来创建这些组件,以便它们可以根据运行平台的不同而自动适配。
Java Swing:与AWT类似,Swing组件也使用了抽象工厂模式来创建组件,以便它们可以根据不同的Look and Feel(比如Windows, Motif, Metal等)来改变外观。
JDBC(Java Database Connectivity):JDBC使用抽象工厂模式来创建数据库连接。DriverManager 类充当抽象工厂,它根据URL的不同来创建不同数据库的连接(例如MySQL, Oracle, SQL Server等)。
Java XML解析:在解析XML文档时,可以使用抽象工厂模式来创建不同的解析器。例如,可以根据需要创建SAX或DOM解析器的实例。
Java国际化(Internationalization, I18N):在处理国际化时,可以使用抽象工厂模式来创建不同语言环境的资源包。
Java Logging API:Java的日志记录框架(如Log4j, SLF4J等)通常使用抽象工厂模式来创建日志记录器实例,以便可以根据配置动态地选择不同的日志实现。
Spring Framework:Spring框架广泛使用了抽象工厂模式来创建bean。例如,BeanFactory 和 ApplicationContext 都是抽象工厂,它们负责根据配置文件或注解来创建和管理bean的生命周期。
Java ImageIO:ImageIO 类是一个抽象工厂,用于创建图像输入/输出处理的流。它可以根据图像格式(如JPEG, PNG, GIF等)来创建相应的图像读取器和写入器。

4. Spring 哪些地方用到了工厂模式

BeanFactory:BeanFactory 是Spring中最基本的抽象,它是一个工厂模式的实现,负责创建和管理bean的生命周期。BeanFactory 根据配置信息来创建bean,并且可以管理bean之间的依赖关系。
ApplicationContext:ApplicationContext 是 BeanFactory 的超集,它也实现了工厂模式。与 BeanFactory 相比,ApplicationContext 提供了更多的功能,如事件传播、资源加载、国际化消息处理等。
FactoryBean:Spring提供了一个名为 FactoryBean 的接口,允许开发者创建自己的工厂来生成复杂的对象。实现这个接口的类可以作为工厂,Spring容器会调用其 getObject 方法来获取bean实例。
ObjectFactory:ObjectFactory 是一个简单的工厂接口,它只有一个方法 getObject。这个接口通常用于延迟加载场景,可以在需要的时候才创建对象。
JdbcTemplate 和数据源:Spring的 JdbcTemplate 类依赖于数据源来获取数据库连接。数据源的创建通常是通过工厂模式来实现的,可以根据配置动态地创建不同类型的数据源实例。
事务管理:Spring的事务管理也使用了工厂模式。例如,TransactionManager 是一个抽象工厂,它根据配置来创建和管理事务。
AOP代理创建:Spring的AOP框架使用工厂模式来创建代理对象。根据配置的不同,Spring可以创建JDK动态代理或CGLIB代理。
消息服务:Spring的JMS模块使用工厂模式来创建消息生产者和消费者。
资源加载:Spring的 ResourceLoader 是一个抽象工厂,它根据资源路径来创建 Resource 对象。
事件发布:Spring的事件发布机制也使用了工厂模式,ApplicationEventPublisher 负责创建和发布事件。
Spring框架的设计哲学之一就是依赖注入(DI),它允许将对象之间的依赖关系外部化,由容器来管理。工厂模式是实现依赖注入的关键机制之一,它允许Spring容器根据配置来创建和管理对象,从而提供了极大的灵活性和扩展性。

标签:Spring,模式,工厂,抽象,创建,设计模式,public
From: https://blog.csdn.net/qq_43196617/article/details/139452302

相关文章

  • C语言判断文件存在和创建文件
    用C语言可以实现新建文件,这里要用到一个fopen函数,它是一个非常强大的函数,可以以各种方式创建、读取文件,具体语法如下:文件指针名=fopen(文件名,使用文件方式);“文件指针名”必须是被说明为File类型的指针变量;“文件名”是被打开文件的文件名,也包括路径;“使用文件方式”是指文件的......
  • 基于Python+OpenCV使用DNA编码和混沌图创建图像加密算法
    欢迎大家点赞、收藏、关注、评论啦,由于篇幅有限,只展示了部分核心代码。文章目录一项目简介二、功能三、系统四.总结一项目简介  一、项目背景与意义在数字信息时代,图像作为信息的重要载体,其安全性尤为重要。传统的图像加密方法往往存在安全性不足、加密效......
  • 如何建立个人品牌和个人IP:创建你的业务的7个步骤
    如果您想建立个人品牌业务,您可能已经意识到,您的工作被机器人和系统取代只是时间问题。自动化和人工智能不可避免地会扰乱整个劳动力市场。那么,您准备如何应对这种变化?你如何适应新世界?具体来说,将您的想法和技能转变为合法的商业和媒体业务的过程是什么?在这篇文章中,我将通过一......
  • Rails - 如何创建关联到 2 个子类的 SIngle Table 继承的一部分
    因此,我设置了单表继承,这样我就可以为User表创建两个子类。在我当前的实现中,这两个子类将拥有完全相同的字段,因此我认为STI在这里是有意义的。类User<ApplicationRecord结束类Student<用户结束类教师<用户结束类约会<应用记......
  • 使用Venv创建Python的虚拟环境
    创建虚拟环境python3-mvenv<directory_name>激活虚拟环境source<directory_name>/bin/active检查当前使用的是哪个Python下面这条命令会输出当前使用Python环境的目录:whichpython配置好之后使用pip安装的库就会默认放在这个环境中停用当前环境deactivate重启环......
  • Maven实战: 创建自定义archetype
    在手动创建SpringBoot应用中,我们讲过手动创建SpringBoot工程是比较麻烦的,尤其是公司内部不有自定义扩展和集成的情况下。利用Maven的archetype:generate能基于项目模板生成功能,自定义模板能让整个创建过程自动化,这样既能大大降低创建和集成SpringBoot的复杂度,还能做到公司内部......
  • (JAVA)设计模式-两阶段终止模式
    `publicclassTowPhaseTermination{publicThreadthread;publicvoidstart(){thread=newThread(newRunnable(){@Overridepublicvoidrun(){while(true){booleaninterrupted=Thread.currentThread().isIn......
  • 实验10 数据库索引创建与管理操作
    1、使用MySQL Navicat图形工具创建、管理索引在JXGL数据库中进行以下操作:创建索引。为students表的sname字段创建索引ix_sname。CREATEINDEXix_snameonstudents(sname)在students表的class和sdept字段上创建名为ix_cs的组合索引。CREATEINDEXix_csonstud......
  • containerd 源码分析:创建 container(三)
    文接containerd源码分析:创建container(二)1.2.2.2启动task上节介绍了创建task,task创建之后将返回response给ctr。接着,ctr调用task.Start启动容器。//containerd/client/task.gofunc(t*task)Start(ctxcontext.Context)error{ r,err:=t.client.TaskServi......
  • 【Java基础】线程的概念、特点及创建线程的三种方式
    线程概念程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。进程:是执行程序的一次执行过程,她是一个动态的概念,是系统资源分配的单位。正在运行的程序在内存中开辟相应的空间。线程:负责程序执行的一条执行路径,是CPU调度和执行的单位。进程和线程......