当前位置: 首页 > article >正文

【设计模式】-工厂模式

工厂模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方法。工厂模式的核心思想是将对象的创建与使用分离,降低系统的耦合度,使系统更加灵活、可扩展。

工厂模式主要分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。下面我将分别介绍这三种工厂模式,并给出相应的Java实例代码。

三种模式介绍

1. 简单工厂模式

简单工厂模式又称为静态工厂方法模式,它由一个工厂类根据传入的参数决定创建哪一种产品类的实例。
在这里插入图片描述

Java实例代码:

// 产品接口
public interface Car {
    void drive();
}

// 具体产品类1
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("Driving BMW");
    }
}

// 具体产品类2
public class Benz implements Car {
    @Override
    public void drive() {
        System.out.println("Driving Benz");
    }
}

// 工厂类
public class CarFactory {
    public static Car createCar(String type) {
        if ("BMW".equalsIgnoreCase(type)) {
            return new BMW();
        } else if ("Benz".equalsIgnoreCase(type)) {
            return new Benz();
        } else {
            throw new IllegalArgumentException("Invalid car type: " + type);
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Car bmw = CarFactory.createCar("BMW");
        bmw.drive();
        
        Car benz = CarFactory.createCar("Benz");
        benz.drive();
    }
}

2. 工厂方法模式

工厂方法模式将对象的创建延迟到子类中进行,工厂类不再负责具体产品的创建,而是提供一个创建产品的抽象方法,由子类实现具体的创建逻辑。
在这里插入图片描述

Java实例代码:

// 产品接口
public interface Car {
    void drive();
}

// 具体产品类1
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("Driving BMW");
    }
}

// 具体产品类2
public class Benz implements Car {
    @Override
    public void drive() {
        System.out.println("Driving Benz");
    }
}

// 工厂接口
public interface CarFactory {
    Car createCar();
}

// 具体工厂类1
public class BMWFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new BMW();
    }
}

// 具体工厂类2
public class BenzFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benz();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        CarFactory bmwFactory = new BMWFactory();
        Car bmw = bmwFactory.createCar();
        bmw.drive();
        
        CarFactory benzFactory = new BenzFactory();
        Car benz = benzFactory.createCar();
        benz.drive();
    }
}

3. 抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)提供了一种方式来封装一组具有共同主题的单个工厂,而不需要指定它们的具体类。客户端使用抽象工厂来创建一系列的相关或相互依赖的对象,而不需要指定它们具体的类。这样可以将客户端与具体产品的创建分离,使得系统更易于扩展和维护。
在这里插入图片描述

下面是一个简单的Java代码实例,展示了抽象工厂模式的应用:

// 抽象产品A
public interface Gui {
    void draw();
}

// 具体产品A1
public class WinGui implements Gui {
    @Override
    public void draw() {
        System.out.println("Drawing Windows GUI");
    }
}

// 具体产品A2
public class MacGui implements Gui {
    @Override
    public void draw() {
        System.out.println("Drawing MacOS GUI");
    }
}

// 抽象产品B
public interface Button {
    void click();
}

// 具体产品B1
public class WinButton implements Button {
    @Override
    public void click() {
        System.out.println("Clicking Windows Button");
    }
}

// 具体产品B2
public class MacButton implements Button {
    @Override
    public void click() {
        System.out.println("Clicking MacOS Button");
    }
}

// 抽象工厂
public interface UiFactory {
    Gui createGui();
    Button createButton();
}

// 具体工厂1
public class WinUiFactory implements UiFactory {
    @Override
    public Gui createGui() {
        return new WinGui();
    }

    @Override
    public Button createButton() {
        return new WinButton();
    }
}

// 具体工厂2
public class MacUiFactory implements UiFactory {
    @Override
    public Gui createGui() {
        return new MacGui();
    }

    @Override
    public Button createButton() {
        return new MacButton();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 使用Windows风格的UI组件
        UiFactory winFactory = new WinUiFactory();
        Gui winGui = winFactory.createGui();
        Button winButton = winFactory.createButton();
        winGui.draw();
        winButton.click();
        
        // 使用MacOS风格的UI组件
        UiFactory macFactory = new MacUiFactory();
        Gui macGui = macFactory.createGui();
        Button macButton = macFactory.createButton();
        macGui.draw();
        macButton.click();
    }
}

在这个例子中,我们定义了两个抽象产品:GuiButton,分别代表图形用户界面和按钮。然后,我们为每种操作系统(Windows和MacOS)创建了具体的产品实现。WinGuiMacGuiGui 的具体实现,而 WinButtonMacButtonButton 的具体实现。

我们定义了一个抽象工厂接口 UiFactory,它包含了创建 GuiButton 的方法。然后,我们为每种操作系统创建了一个具体的工厂实现:WinUiFactoryMacUiFactory。这些工厂负责创建对应操作系统的具体产品实例。

在客户端代码中,我们可以根据需要选择使用哪种风格的UI组件。通过创建不同风格的工厂实例,并调用其创建方法,我们可以得到对应风格的 GuiButton 对象,并调用它们的方法。这样,客户端代码与具体产品的创建逻辑被完全分离,提高了系统的灵活性和可维护性。

对比

是不是还有点晕,好像“工厂方法模式”和“抽象工厂模式”傻傻分不清楚啊。那我们来张表对比一下,就清晰了:

特性/模式简单工厂模式工厂方法模式抽象工厂模式
结构一个工厂类负责创建所有产品抽象工厂类定义接口,具体工厂类负责创建对应产品抽象工厂类定义创建产品族的接口,具体工厂类负责创建多个具体产品
扩展性不符合“开闭原则”,新增产品需修改工厂类符合“开闭原则”,新增产品只需添加新类和工厂子类新增产品族符合“开闭原则”,单独新增产品不符合
使用场景产品种类少且不常变动产品种类多且经常变动需要创建一系列相互关联或依赖的产品
责任划分工厂类负责创建所有产品实例具体工厂子类负责创建对应产品实例具体工厂子类负责创建多个相互关联的产品实例
客户端与产品创建客户端直接调用工厂类创建产品客户端通过工厂子类接口创建产品客户端通过工厂子类接口创建多个相关产品
灵活性较低,工厂类集中了所有产品创建逻辑较高,产品创建逻辑分散在工厂子类中较高,可以灵活创建多个相关产品
代码复杂性较低,结构简单中等,需要定义抽象工厂和具体工厂类较高,涉及多个抽象产品类和具体产品类

了解下“产品族”是个啥:
在这里插入图片描述
在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。这些产品虽然在类型上有所差异,但它们在功能上是相互关联或依赖的。

为了更好地理解这个概念,我们可以以一个实际的例子来说明。假设有一个电器制造工厂,它生产了电视机和电冰箱两种产品。这两种产品分别属于不同的产品等级结构:电视机有其自己的产品等级结构,包括不同品牌、型号的电视机;电冰箱也有其独立的产品等级结构,涵盖了各种类型、规格的电冰箱。然而,在这个例子中,由于它们都是由同一个电器制造工厂生产的,因此电视机和电冰箱构成了一个产品族。

这个产品族中的每个成员(即电视机和电冰箱)都有其特定的功能和用途,但它们都是电器制造工厂的产品,共享了相同的生产标准和质量控制体系。因此,它们在功能上是相互关联或依赖的,构成了一个有机的整体。

抽象工厂模式通过提供一个接口,使得客户端可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。在上面的例子中,客户端可以通过调用电器制造工厂的接口,一次性地获取到电视机和电冰箱这两种产品,而无需关心它们具体的实现细节。

这下是不是就清晰了。OVER。


http://www.kler.cn/a/273268.html

相关文章:

  • selinux和防火墙
  • 常用的 Lambda 表达式案例解析
  • Vue2指令原理手写
  • 中文分词模拟器
  • Linux第二周作业
  • 计算机网络:网络层 —— 多播路由选择协议
  • CLIP解读
  • Java基础-lambda表达式
  • C++_day6:继承、多态
  • arcgis 点连接到面(以地级市图层为例)
  • 【计算机网络】集线器
  • upload-labs-pass01
  • 1.中医学习-总论
  • 使用exe4j将java项目打包为exe文件(包含普通maven项目打jar包)
  • PostgreSQL中vacuum 物理文件truncate发生的条件
  • 牛客题霸-SQL入门篇(刷题记录二)
  • 通过调整报文偏移解决CAN应用报文丢帧或周期过长问题
  • RVA和FOA转换---三
  • 独立维基和验收测试框架 Fitnesse 入门介绍
  • 数据结构与算法Bonus-KNN问题的代码求解过程
  • java15~17 密封类
  • 【JS逆向学习】猿人学第六题 js混淆 回溯
  • 数目之差
  • 【Paper Reading】6.RLHF-V 提出用RLHF的1.4k的数据微调显著降低MLLM的虚幻问题
  • upload-labs 0.1 靶机详解
  • 【Spring MVC】Spring MVC拦截器(Interceptor)