设计模式——工厂模式

定义:

​ 工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。

本章代码:小麻雀icknn/设计模式练习 - Gitee.com

工厂模式分三类

  1. 简单工厂模式(Simple Factory)
  2. 工厂方法模式(Factory Method)
  3. 抽象工厂模式(Abstract Factory)

在《设计模式》一书中工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。简单工厂模式(Simple Factory)

简单工厂

简单工厂,工厂模式定义:提供创建对象的接口。简单工厂模式(Simple Factory Pattern)属于类的创建型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂中的角色

1.Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

2.IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

3.Product:具体产品类,是简单工厂模式的创建目标。

简单理解:一个工厂(Factory工厂类),有一系列产品(IProduct抽象产品类),该系列产品都有哪种型号(Product具体产品类)

举例:

Factory:工厂类

java 复制代码
package com.study.main;

public class ToolFactory {
    public ToolInterface getTool(String name){
        if(name.equals("Tongs")){
           return new Tongs(name);
        }
        if(name.equals("Hammer")){
            return new Hammer(name);
        }
        return null;
    }
}

IProduct:抽象产品类

java 复制代码
package com.study.main;

public interface ToolInterface {
    public String name ();
    public void methods();
}

Product:具体产品类

java 复制代码
package com.study.main;

public class Hammer implements ToolInterface{
    public String name;

    public Hammer(String name) {
        this.name = name;
    }

    @Override
    public String name() {

        return this.name;
    }

    @Override
    public void methods() {
        System.out.println(this.name);
    }
}

public class Tongs implements ToolInterface{
    public String name;
    public Tongs(String name) {
        this.name = name;
    }
    @Override
    public String name() {

        return this.name;
    }

    @Override
    public void methods() {
        System.out.println(this.name);
    }
}

调用:

java 复制代码
package com.study.main;

public class FactoryMain {
    public static void main(String[] args) {
        ToolFactory toolFactory = new ToolFactory();
        ToolInterface tongs = toolFactory.getTool("Hammer");
        tongs.methods();
    }
}

优点:

  1. 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
  2. 客户端无需知道所创建具体产品的类名,只需知道参数即可。
  3. 也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。

缺点:

  1. 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
  2. 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度。
  3. 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
  4. 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。

违反了开闭原则,所以不常用

工厂方法模式

工厂方法模式属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义在于定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,仅负责声明具体工厂子类必须实现的接口。这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式的主要角色

  • Abstract Factory 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  • Concrete Factory 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • Product 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
  • Concrete Product 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

UML图

举例

抽象工厂 接口

java 复制代码
package com.study.main.FactoryMethod;

public interface Factory {
    void method();
}

抽象产品 接口

java 复制代码
package com.study.main.FactoryMethod;

public interface Tool {
    String name();
}

具体工厂1

java 复制代码
package com.study.main.FactoryMethod;

public class TongsFactory implements Factory{

    @Override
    public void method() {
        String tongs = new Tongs("Tongs").name();
        System.out.println(tongs);
    }
}

具体工厂 2

java 复制代码
package com.study.main.FactoryMethod;

public class HammerFactory implements Factory{
    @Override
    public void method() {
        String hammer = new Hammer("Hammer").name();
        System.out.println(hammer);
    }
}

具体产品1

java 复制代码
package com.study.main.FactoryMethod;

public class Tongs implements Tool{
    String name;

    public Tongs(String name) {
        this.name = name;
    }

    @Override
    public String name() {
        return this.name;
    }
}

具体产品2

java 复制代码
package com.study.main.FactoryMethod;

public class Hammer implements Tool{
    String name;

    public Hammer(String name) {
        this.name = name;
    }

    @Override
    public String name() {
        return this.name;
    }
}

调用

java 复制代码
package com.study.main.FactoryMethod;

import com.study.main.ToolFactory;

public class FactoryMethodMain {
    public static void main(String[] args) {
        new HammerFactory().method();
        new TongsFactory().method();
    }
}

优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:

  • 类的个数容易过多,增加复杂度。
  • 增加了系统的抽象性和理解难度。
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

抽象工厂

是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式的主要角色

  • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
  • 抽象工厂:提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  • 具体工厂:主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。

UML图

例子:

抽象接口

java 复制代码
package com.study.main.AbstractFactory;

public interface AbstractFactory {
    Pencil createPencil();
    Eraser createEraser();
}
package com.study.main.AbstractFactory;

public interface Eraser {
    void erase();
}
package com.study.main.AbstractFactory;

public interface Pencil {
    void draw();
}

抽象类

java 复制代码
package com.study.main.AbstractFactory;

public class ChenGuangEraser implements Eraser{
    @Override
    public void erase() {
        System.out.println("----------ChenGuang Erase---------------");
    }
}

package com.study.main.AbstractFactory;

public class ChenguangFactory implements AbstractFactory{
    @Override
    public Pencil createPencil() {
        return new ChenGuangPencil();
    }

    @Override
    public Eraser createEraser() {
        return new ChenGuangEraser();
    }
}

package com.study.main.AbstractFactory;

public class ChenGuangPencil implements Pencil{
    @Override
    public void draw() {
        System.out.println("----------ChenGuang Draw---------------");
    }
}

package com.study.main.AbstractFactory;

public class TrueColorEraser implements Eraser{
    @Override
    public void erase() {
        System.out.println("----------TrueColor Erase---------------");
    }
}
package com.study.main.AbstractFactory;

public class TrueColorFactory implements AbstractFactory{

    @Override
    public Pencil createPencil() {
        return new TrueColorPencil();
    }

    @Override
    public Eraser createEraser() {
        return new TrueColorEraser();
    }
}

package com.study.main.AbstractFactory;

public class TrueColorPencil implements Pencil{
    @Override
    public void draw() {
        System.out.println("----------TrueColor Draw---------------");
    }
}

优点:

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
  • 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
  • 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。

缺点:

  • 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
  • 模式的结构与实现
  • 抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。

Spring中的应用:

相关推荐
Scott9999HH1 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json