首页 > 其他分享 >工厂方法模式

工厂方法模式

时间:2023-09-13 16:22:48浏览次数:28  
标签:创建 代码 模式 工厂 具体 产品 方法 客户端

当设计应用程序时,对象的创建过程是一个关键的考虑因素。工厂方法模式(Factory Method Pattern)是一种创建型设计模式,用于解决对象的创建与客户端代码之间的紧耦合问题。通过引入一个工厂接口和多个具体工厂类,工厂方法模式将对象的创建过程抽象化,使得客户端代码无需直接实例化对象,而是通过工厂来获取所需的对象。

工厂方法模式的核心概念

  1. 抽象产品(Abstract Product):定义了产品的接口或抽象类,它是具体产品的父类,规定了产品应该具有的方法和属性。

  2. 具体产品(Concrete Product):实现了抽象产品接口或继承了抽象产品类的具体类,它们是工厂方法模式中真正创建的对象。

  3. 抽象工厂(Abstract Factory):定义了工厂方法的接口或抽象类,包含一个用于创建产品的抽象方法。这个抽象工厂可以有多个具体工厂的实现,每个具体工厂可以创建一组相关的具体产品。

  4. 具体工厂(Concrete Factory):实现了抽象工厂的具体类,它负责创建一组具体产品的对象。

工厂方法模式的工作原理

工厂方法模式的工作原理如下:

  1. 客户端代码需要创建一个产品对象,但不知道具体产品的类名。
  2. 客户端代码调用抽象工厂的工厂方法,该方法返回一个抽象产品的引用。
  3. 具体工厂类的工厂方法被调用,它实际上会创建一个具体产品的实例,并将其返回给客户端。
  4. 客户端代码可以使用抽象产品的引用来访问产品的方法和属性,而不需要知道具体产品的类名。

示例代码

假设我们有一个图形绘制应用程序,可以绘制不同类型的图形,如圆形和矩形。我们可以使用工厂方法模式来创建这些图形对象。

// 抽象产品:图形
interface Shape {
    void draw();
}

// 具体产品:圆形
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

// 具体产品:矩形
class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

// 抽象工厂:图形工厂
interface ShapeFactory {
    Shape createShape();
}

// 具体工厂:圆形工厂
class CircleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

// 具体工厂:矩形工厂
class RectangleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}

在上述示例中,我们定义了抽象产品 Shape 和具体产品 Circle 和 Rectangle。然后,我们定义了抽象工厂 ShapeFactory 和两个具体工厂 CircleFactory 和 RectangleFactory。客户端代码可以通过调用工厂的方法来创建具体产品的对象,而不需要直接实例化具体产品。

客户端代码如何使用工厂方法模式

客户端代码使用工厂方法模式的步骤如下:

  1. 创建具体工厂对象,选择所需的产品族(例如,CircleFactory 或 RectangleFactory)。
  2. 调用具体工厂对象的工厂方法(例如,createShape() 方法)来创建具体产品对象。
  3. 使用抽象产品的引用来访问产品的方法和属性。
    下面是客户端代码的示例:
public class Client {
    public static void main(String[] args) {
        // 使用具体工厂创建具体产品
        ShapeFactory circleFactory = new CircleFactory();
        Shape circle = circleFactory.createShape();
        circle.draw(); // 输出:绘制圆形

        ShapeFactory rectangleFactory = new RectangleFactory();
        Shape rectangle = rectangleFactory.createShape();
        rectangle.draw(); // 输出:绘制矩形
    }
}

通过这种方式,客户端代码无需知道具体产品的类名,只需通过工厂接口来获取所需的对象,使代码更具可维护性和扩展性。

适用环境

  1. 当一个类不知道它所需要的对象的类时:客户端代码只需要知道产品的抽象接口或父类,而不需要了解具体的实现类。这对于减少耦合度和提高代码的可维护性非常有帮助。

  2. 当一个类希望由其子类来指定创建对象的具体类时:工厂方法模式允许子类决定创建哪个具体类的对象,从而在运行时实现多态。

  3. 当一组相关的对象需要一起创建时:工厂方法模式可以确保创建的产品是兼容的,因为每个具体工厂负责创建一组相关的产品。

  4. 当需要在不同的地方或时间创建对象实例时:工厂方法模式允许在不同的情况下使用不同的工厂来创建对象,以满足特定的需求。

优点

  1. 降低耦合度:工厂方法模式将对象的创建过程与客户端代码分离,客户端只需要与抽象工厂和产品接口交互,无需关心具体的实现类,降低了代码的耦合度。

  2. 可扩展性:可以轻松添加新的产品或工厂类,而不会影响现有的客户端代码,使系统更具扩展性。

  3. 符合开闭原则:对扩展开放,对修改封闭。通过添加新的具体工厂和产品类,可以扩展系统功能而无需修改现有代码。

  4. 多态性:工厂方法模式允许子类决定创建哪个具体类的对象,从而实现多态性,增加了代码的灵活性。

缺点

  1. 类的数量增加:每个产品都需要一个具体工厂类,可能会导致类的数量增加,使项目结构复杂。

  2. 增加了代码复杂性:相对于直接实例化对象,使用工厂方法模式需要多写一些额外的代码,可能会增加代码的复杂性。

  3. 不适用于简单对象创建:对于创建简单的对象,工厂方法模式可能会显得繁琐,不适合所有情况。

总的来说,工厂方法模式是一种非常有用的设计模式,特别适用于需要灵活创建对象、降低耦合度和提高可维护性的情况。然而,它也需要权衡使用,因为在某些情况下,可能会引入额外的复杂性。在设计和开发时,需要根据具体需求和情况来决定是否使用工厂方法模式。

标签:创建,代码,模式,工厂,具体,产品,方法,客户端
From: https://www.cnblogs.com/Cloong/p/17699984.html

相关文章

  • Redis哨兵模式详解
    目录Redis哨兵模式定义为什么需要Redis哨兵模式?Redis哨兵模式功能Redis哨兵模式原理Redis哨兵模式的优缺点 Redis哨兵模式定义Redis哨兵模式是是一个管理多个Redis实例的工具,它可以实现对Redis的监控、通知、自动故障转移,是Redis实现高可用的实现方案。 为什么需要Red......
  • 《精通Python设计模式》 PDF电子书 +源码
    第1章工厂模式第2章建造者模式第3章其他创建型模式第4章适配器模式第5章装饰器模式第6章桥接模式第7章外观模式第8章其他结构型模式第9章职责链模式第10章命令模式第11章观察者模式第12章状态模式第13章其他行为型模式第14......
  • 单例模式
    面向对象编程中,单例模式是一个经常被讨论的话题。单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一种全局访问点来获取该实例。在本篇博客中,我们将深入探讨单例模式的重要概念、实现方式、以及何时使用它。什么是单例模式?单例模式是一种确保在整个应用程序中......
  • 观察者模式
    观察者模式,也称发布订阅模式,主题方发布,观察方订阅。observe.h/***Copyright(C)2023-09-1314:06zxinlog<[email protected]>**/#include<func.h>#include<iostream>#include<list>usingstd::cout;usingstd::endl;usingstd::list;classObserve......
  • Qt Debug 不下去的一个解决方法
    今天遇到一个难题。在debug时,使用qt函数载入自写的dll时,载入时,崩溃。如果不用F5可以顺利运行删除临时文件文件夹等方式都试过,问题依然存在。当我删除所有的断点后,重新编译,然后设置断点,跟踪运行正常。问题原因没有找到。错误关键词:ZwMapViewOfSection ......
  • 03-开发环境介绍_交互模式的使用_IDLE介绍和使用
       ......
  • 两个numpy技巧(模式识别总结)
    1.查找符合特定条件的Numpyndarray对象中元素的数量np.count_nonzero()函数可以用来完成此操作。以下是使用np.count_nonzero()函数快速查找数组中小于5的元素数量的示例:count=np.count_nonzero(array<5)在此示例中,我们使用array<5来获取array中小于5的所有元素,然后......
  • Java多线程____线程yield方法介绍
    packagecom.test.thread;publicclassTestYield{ publicstaticvoidmain(String[]args){ TestThreadt1=newTestThread("A_01"); TestThreadt2=newTestThread("B_02"); t1.start(); t2.start(); }}classTestThreadextend......
  • Java多线程____线程状态Join()方法
    代码:packagecom.test.thread;publicclassTestRunnableimplementsRunnable{ @Override publicvoidrun(){ synchronized(this){ for(inti=0;i<10;i++){ System.out.println(Thread.currentThread().getName()); } } } }packagecom......
  • Java多线程____线程状态Sleep()方法
    Sleep():在指定的毫秒数内让当前正在执行的线程休眠调用sleep方法时使当前的线程进入休眠状态(阻塞状态)设定休眠xxxx毫秒数后进入运行状态同步块中的Sleep方法调用不会释放对象锁但调用wait()方法会释放对象的同步锁packagecom.test.thread;publicclassTestRunnableimpleme......