首页 > 其他分享 >设计模式-工厂模式设计与详解

设计模式-工厂模式设计与详解

时间:2024-09-02 19:57:06浏览次数:10  
标签:use 创建 模式 工厂 详解 产品 设计模式 class

一、工厂模式概述

工厂模式(Factory Pattern)是一种常用的创建型设计模式,其核心目的是实现创建对象的接口和具体的实例化分离,通过建立一个工厂类,对实现了同一接口的一些类进行实例的创建,以增加系统的灵活性和可维护性。

当需要大量创建一个类的实例的时候,可以使用工厂模式,即从原生的使用类的构造去创建对象的形式迁移到基于工厂提供的方法去创建对象的形式。基于工厂模式的实例创建具有以下好处:

  • 大批量创建对象的时候有统一的入口,易于代码维护;
  • 当发生修改时,仅需修改工厂类的创建方法即可;
  • 符合现实世界的模式,即由工厂来制作产品(对象);

本文将通过类图及示例代码详细介绍工厂模式的三种形式:简单工厂模式工厂方法模式抽象工厂模式

设计模式-工厂模式设计与详解_Java


二、简单工厂模式

简单工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,让其子类决定实例化哪一个类。该模式将对象的创建集中管理,通过专门的工厂类来负责创建所有实例,这样可以避免在客户代码中重复创建对象,降低系统的耦合度,提高模块的可复用性。

1. 简单工厂模式类图

以下类图展示了简单工厂模式的结构:

设计模式-工厂模式设计与详解_简单工厂_02

classDiagram
    class Client {
    }

    class Factory {
        +createProduct(type) Product
    }

    class Product {
        <<interface>>
        +use()
    }

    class ConcreteProductA {
        +use()
    }

    class ConcreteProductB {
        +use()
    }

    Client --> Factory : uses
    Factory --> Product : creates
    ConcreteProductA --|> Product
    ConcreteProductB --|> Product

在这个类图中,Client 不直接与具体产品类(ConcreteProductAConcreteProductB)交互,而是通过 Factory 类来进行。这样做的优点是客户端从具体产品的创建过程中解耦,提高了程序的扩展性和可维护性。


2. 简单工厂模式示例代码

下面的示例代码进一步阐释了简单工厂模式的应用:

  • 抽象产品:定义了产品的接口,所有的产品都必须实现这个接口。
interface Product {
    void use();
}
  • 具体产品:实现了产品接口的实体类,定义了具体产品的行为。
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using ConcreteProductA");
    }
}

class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using ConcreteProductB");
    }
}
  • 简单工厂:一个工厂类,提供了一个创建对象的方法,客户端通过调用这个方法并传入参数来创建不同的产品实例。
class Factory {
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ConcreteProductA();
        } else if (type.equals("B")) {
            return new ConcreteProductB();
        }
        return null;
    }
}
  • 调用简单工厂示例:客户端使用 Factory 类创建具体的产品实例。这种方式的主要优点是工厂类包含必要的逻辑判断,可以决定在运行时创建哪个产品的实例。由于使用了工厂类,客户端可以完全从具体产品的实现中解耦,只需要关心产品的接口。
public class Client {
    public static void main(String[] args) {
        Product product = Factory.createProduct("A");
        product.use();
    }
}

通过这种方式,简单工厂模式使得新增产品类时,只需要扩展工厂类而不需要修改现有的客户代码,从而增加了系统的灵活性。

也就是将"A"换成其他产品,如果产品类不存在,我们需要新增产品类,同时添加createProduct里type为新产品的情况,其实还是有点麻烦的,所有下面的工厂方法就是对此的改进。


三、工厂方法模式

工厂方法模式是一种创建型设计模式,它提供了一个创建对象的方法,但实际的工作将由子类完成,这样的设计模式可以让类的实例化推迟到其子类中进行。这种模式通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类,从而使代码管理更加简单,同时也扩展了系统的可能功能。

1. 工厂方法模式类图

下面的类图描述了工厂方法模式的结构:

设计模式-工厂模式设计与详解_简单工厂_03

在这个模式中,Creator 类定义了一个抽象的 factoryMethod(),该方法需要被子类实现以返回一个 Product 类的实例。这样,客户端代码只依赖于 Product 接口,而具体实例化哪个产品类由具体的 Creator 子类决定,这样提高了系统的灵活性和扩展性。


2. 工厂方法模式示例代码

以下示例代码进一步阐释了工厂方法模式的应用:

  • 产品接口:定义了所有具体产品需要实现的接口。
interface Product {
    void use();
}
  • 具体产品:实现了产品接口的具体类,这些类定义了具体产品的行为。
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using ConcreteProductA");
    }
}

class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using ConcreteProductB");
    }
}
  • 抽象创建者:定义了抽象的工厂方法,由具体创建者来实现。
abstract class Creator {
    abstract Product factoryMethod();
}
  • 具体创建者:继承抽象创建者,实现了工厂方法,决定实际生产的产品。
class ConcreteCreatorA extends Creator {
    @Override
    Product factoryMethod() {
        return new ConcreteProductA();
    }
}

class ConcreteCreatorB extends Creator {
    @Override
    Product factoryMethod() {
        return new ConcreteProductB();
    }
}
  • 客户端使用:客户端代码通过调用工厂方法来获取产品对象,而无需知道具体的产品类。
public class Client {
    public static void main(String[] args) {
        Creator creator = new ConcreteCreatorA();
        Product product = creator.factoryMethod();
        product.use();
    }
}

通过这种方式,工厂方法模式使得添加新产品类时,只需添加一个具体的创建者而无需修改现有代码,符合开闭原则,提高了代码的可维护性和扩展性。

与简单工厂加个产品需要改一揽子的代码相比,工厂方法只需要创建一个新的创建者类,客户端调用时ConcreteCreatorA更换为新类名就可以。


四、抽象工厂模式

抽象工厂模式是创建型设计模式中的一种,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这种模式是工厂方法模式的一种扩展,它用于创建产品家族,而不仅仅是单一产品。通过这种方式,可以增强程序的灵活性和可维护性,同时也支持良好的封装性和扩展性。

1. 抽象工厂模式类图

以下类图清晰展示了抽象工厂模式的结构和组件之间的关系:

设计模式-工厂模式设计与详解_抽象工厂_04

在这个模式中,AbstractFactory 是一个抽象类,定义了创建一系列产品的接口。每个具体工厂类(如 ConcreteFactory1ConcreteFactory2)实现这个接口,生产具体的产品实例。客户端通过使用工厂接口,而不是直接实例化产品,从而使得具体的产品在客户端保持抽象状态。

2. 抽象工厂模式示例代码

以下示例代码详细说明了抽象工厂模式的实现:

  • 产品接口:定义了产品的操作。
interface AbstractProductA {
    void use();
}

interface AbstractProductB {
    void use();
}
  • 具体产品:实现产品接口的具体类。
class ConcreteProductA1 implements AbstractProductA {
    public void use() {
        System.out.println("Using ConcreteProductA1");
    }
}

class ConcreteProductA2 implements AbstractProductA {
    public void use() {
        System.out.println("Using ConcreteProductA2");
    }
}

class ConcreteProductB1 implements AbstractProductB {
    public void use() {
        System.out.println("Using ConcreteProductB1");
    }
}

class ConcreteProductB2 implements AbstractProductB {
    public void use() {
        System.out.println("Using ConcreteProductB2");
    }
}
  • 抽象工厂:定义了创建一系列产品的方法。
abstract class AbstractFactory {
    abstract AbstractProductA createProductA();
    abstract AbstractProductB createProductB();
}
  • 具体工厂:实现抽象工厂,定义了生产具体产品的方式。
class ConcreteFactory1 extends AbstractFactory {
    @Override
    AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

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

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

    @Override
    AbstractProductB createProductB() {


        return new ConcreteProductB2();
    }
}
  • 客户端使用:客户端通过抽象工厂接口创建并使用产品。
public class Client {
    public static void main(String[] args) {
        AbstractFactory factory = new ConcreteFactory1();
        AbstractProductA productA = factory.createProductA();
        AbstractProductB productB = factory.createProductB();
        productA.use();
        productB.use();
    }
}

通过这种方式,抽象工厂模式允许系统在不具体指定产品的情况下创建一系列相关或依赖的对象,支持配置多个工厂,每个工厂创建不同的产品实例,从而增强系统的灵活性和扩展性。

这也是工厂方法模式的升级,虽然在开闭原则上做出了让步,但是为更强的灵活和扩展创造了条件。


五、三种工厂模式异同

首先,我们来看三种工厂模式的定义:

  • 简单工厂模式:最简单的工厂模式,适合产品种类较少且不经常变化的情况。工厂类集中处理所有产品的创建逻辑,这简化了代码但降低了系统的扩展性。
  • 工厂方法模式:允许多个创建者子类来实现具体的产品创建。这种分散的创建过程提高了系统的灵活性,并且增强了代码的可扩展性。
  • 抽象工厂模式:提供一个创建一系列相关或互依赖对象的接口,而无需指定它们具体的类。适用于处理多个系列产品的情况,每个具体工厂都能生产一个完整的产品家族。

接着,我们用一张表来总结三种工厂模式的特性差异:

特点/模式

简单工厂模式

工厂方法模式

抽象工厂模式

定义

提供一个创建对象的接口,由接口决定创建哪一种产品类的实例。

定义一个用于创建对象的接口,但由子类决定要实例化的类是哪一个。

提供一个接口,用于创建相关的对象家族,而不需要明确指定具体类。

对象创建的责任

集中于一个工厂类,通过接收特定参数决定创建对象的类型。

分散到多个子类中,每个子类封装了一个产品的创建过程。

集中于多个工厂类,每个工厂类负责创建一个产品家族。

实现复杂度




灵活性

低,增加新产品需要修改工厂类

高,每个产品有其对应的具体工厂类

非常高,支持创建产品家族且易于添加新的产品组合

产品扩展性

较差,扩展新产品时可能需要修改工厂逻辑

好,扩展新产品时仅需添加相应的具体工厂类

优,允许通过添加具体工厂和产品类的方式来扩展产品家族

应用场景

适用于产品类型数量不多且变动不频繁的情况

适用于一个类族有多个变体,但仅需使用其一的情况

适用于需要创建多系列产品或产品族,且产品族需要一起使用的情况

通过上述表格,我们可以清晰地看到每种工厂模式的特点及其适用的场景。在不同的开发需求下,我们需要选择最合适的模式。


六、工厂模式的优势与应用场景

1. 工厂模式的优势

优势

说明

封装性

用户仅需知道产品对应的工厂名,无需关心产品的具体创建细节,从而降低了系统的复杂度。

扩展性

新增产品时,只需扩展一个工厂类,而不需修改现有代码,符合开闭原则,易于系统扩展和维护。

解耦

分离了产品的实例化过程,使用抽象层促使产品的实现和使用分离,提高了系统的灵活性和可维护性。

代码可维护性

由于工厂类和产品类的职责清晰,系统的不同部分可以独立变化而互不影响,从而提高代码的可维护性。

2. 工厂模式的应用场景

  • 当系统中的产品有多于一个的产品族,而系统只消费其中某一产品族时。
  • 当属于同一个产品族的一组产品被设计用于一起使用时,可以使用抽象工厂模式。
  • 当系统需要被配置成一个具有多个不同行为的产品组成时,可以使用工厂模式确保其灵活性和可扩展性。

七、工厂模式总结

工厂模式是设计模式中非常关键的一类,主要用于解决对象创建过程中的复杂性,并帮助将对象的实例化过程与使用者分离,从而增加系统的整体封装性和灵活性。通过定义一个用于创建对象的接口,允许子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。这种模式不仅帮助管理和维护大型软件系统中的对象创建问题,也使系统更加模块化,易于理解和扩展。总的来说,工厂模式在需要生成复杂对象时,提供了极大的便利和高效的管理与维护策略。

标签:use,创建,模式,工厂,详解,产品,设计模式,class
From: https://blog.51cto.com/liuguangzhi/10776183

相关文章

  • flash详解
    flash详解什么是FlashFlash全名叫做FlashMemory,从名字就能看出,是种数据存储设备,存储设备有很多类,Flash属于非易失性存储设备(Non-volatileMemoryDevice),与此相对应的是易失性存储设备(VolatileMemoryDevice)。关于什么是非易失性/易失性,从名字中就可以看出,非易失性就是不容......
  • 设计模式-工厂方法模式
    ......
  • 设计模式之备忘录模式
    备忘录模式(MementoPattern)官方的定义是这样的:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。它是面向对象的23种设计模式中的一种,属于行为模式的范围。直白点说就是:我们可以在不暴露更多字段的前提下,直接将......
  • 详解 ThreadPoolExecutor 的参数含义及源码执行流程?
    Java学习+面试指南:https://javaxiaobear.cn线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术,它是把已创建的线程放入“池”中,当有任务来临时就可以重用已有的线程,无需等待创建的过程,这样就可以有效提高程序的响应速度。但如果要说线程池的话一定离不开Th......
  • java定义通用返回结果类ResultVO使用示例详解
    java定义通用返回结果类ResultVO使用示例详解定义通用返回结果类定义ResultVO类,作返回给前端的对象结构,主要有4个字段code:错误码data:内容message:消息description:具体描述importlombok.Data;importjava.io.Serializable;/***通用返回结果类*@param<T>*/@D......
  • 【Qt笔记】QTableView控件详解
     目录引言 一、定义与架构二、主要功能与特点2.1 显示表格数据2.2编辑表格数据2.3自定义外观和交互2.4数据排序和过滤2.5支持拖放操作2.6自适应大小2.7上下文菜单2.8信号与槽三、常用属性设置3.1设置模型3.2 设置选择模型3.3 隐藏垂直标题3.4 ......
  • 【C语言】文件操作(详解)
    文章目录1.为什么需要文件?2.什么是文件?2.1文件分类2.2文件名3.文件的使用3.1文件指针3.2打开和关闭文件3.2.1文件使用方式3.2.2标准输入输出流3.3文件输入输出函数3.3.1字符输入输出实现文件拷贝3.3.2文本行输入输出3.3.3格式化输入输出3.3.4二进制输入输出3.3.5sscanf/sprintf函......
  • 【C语言】顺序表详解,灵活运用所学知识
    文章目录前言1.什么是顺序表?1.1线性表2.编写你的顺序表!2.0赛前准备2.1初始化2.2容量检查2.3打印顺序表2.4尾插和尾删2.5头插和头删2.6插入和删除2.7查找和更改3.菜单一些err总结前言顺序表是我们学习数据结构第一阶段的必经之路什么是顺序表,且听我慢慢道来本篇博客用到的......
  • 跨境电商寻找新增长点的策略详解
    前言:在全球化和数字化的大潮中,跨境电商已成为推动国际贸易的重要力量。面对不断变化的市场需求和日益激烈的竞争环境,企业必须寻找新的增长点以保持竞争力。本文将探讨跨境电商如何通过深耕特定市场、数据驱动运营和合规经营等策略,实现可持续增长。深耕特定市场与本地化策略市场......
  • ECharts实现雷达图详解
    ECharts是一款由百度开源的数据可视化工具,它提供了丰富的图表类型,如折线图、柱状图、饼图、散点图、雷达图、地图、K线图、热力图、仪表盘等,以及丰富的交互功能。ECharts组件的核心功能实现原理主要包括以下几个方面:数据驱动:ECharts采用数据驱动的设计理念,图表的生成和更新......