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

比简单工厂更好的 - 工厂方法模式(Factory Method Pattern)

工厂方法模式(Factory Method Pattern)

  • 工厂方法模式(Factory Method Pattern)
    • 工厂方法模式(Factory Method Pattern)概述
      • 工厂方法模式(Factory Method Pattern)结构图
      • 工厂方法模式(Factory Method Pattern)涉及的角色
    • talk is cheap, show you my code
    • 总结

工厂方法模式(Factory Method Pattern)

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但由子类决定要实例化的类是哪一个。这种模式让类的实例化推迟到子类,从而实现了创建逻辑与具体实现的分离。通过这种方式,工厂方法模式使得一个框架可以不依赖于具体的类,而只依赖于抽象类或接口,提高了代码的灵活性和可扩展性。

太抽象了
我们先说一下简单工厂,简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
相当于我们有一个工厂类,有一个工厂方法,我们给这个工厂方法传入不同的参数,这个工厂就给我生成不同的对象。但是简单工厂有一个问题就是,如果我们要新增产品,我们就需要修改工厂方法。这样就违反了开闭原则。

工厂方法模式(Factory Method Pattern)概述

工厂方法模式(Factory Method Pattern)结构图

在这里插入图片描述

工厂方法模式(Factory Method Pattern)涉及的角色

  1. 产品接口(Product):声明了所有具体产品必须实现的操作。所有的具体产品类都实现了这个接口或继承自这个抽象类。
public interface Product {void operation();
}
  1. 具体产品(ConcreteProduct):实现了Product接口,提供了具体产品的实现。
public class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}public class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}
  1. 创建者/工厂接口(Creator):接口或抽象类,声明了工厂方法,该方法返回Product类型的对象。创建者还可以包含其他业务逻辑,这些逻辑可以调用工厂方法来创建产品对象。
public abstract class Creator {// 工厂方法public abstract Product factoryMethod();// 其他业务逻辑public void someOperation() {Product product = this.factoryMethod();product.operation(); // 使用创建的产品}
}
  1. 具体创建者(ConcreteCreator):实现了Creator中的工厂方法,每个具体创建者都会返回不同类型的Product对象。
public class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}public class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}

talk is cheap, show you my code

// 定义产品接口
public interface Shape {void draw();
}// 实现具体产品
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle.");}
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a rectangle.");}
}// 定义创建者接口
public abstract class ShapeFactory {public abstract Shape createShape();public void drawShape() {Shape shape = createShape();shape.draw();}
}// 实现具体创建者
public class CircleFactory extends ShapeFactory {@Overridepublic Shape createShape() {return new Circle();}
}public class RectangleFactory extends ShapeFactory {@Overridepublic Shape createShape() {return new Rectangle();}
}// 客户端代码
public class Client {public static void main(String[] args) {ShapeFactory circleFactory = new CircleFactory();circleFactory.drawShape(); // Drawing a circle.ShapeFactory rectangleFactory = new RectangleFactory();rectangleFactory.drawShape(); // Drawing a rectangle.}
}

工作流程

  1. 客户端创建具体的工厂对象(如 CircleFactory 或 RectangleFactory)。
  2. 调用工厂对象的 drawShape() 方法。
  3. drawShape() 方法内部调用 createShape() 方法,由具体的工厂子类决定创建哪种类型的 Shape 实例。
  4. 创建的 Shape 实例的 draw() 方法被执行,输出相应的绘制信息。

总结

工厂方法模式的优点

  • 遵循开闭原则:新增加产品时,只需要添加新的具体产品类和对应的创建者类,无需修改现有代码,这符合面向对象设计中的开闭原则(Open/Closed Principle)。
  • 支持多态行为:客户端代码可以通过基类或接口来操作对象,而不需要关心具体的产品类型。
  • 解耦合:工厂方法模式将创建对象的责任推给了子类,减少了客户端代码与具体产品之间的耦合度。
  • 易于扩展:当需要引入新产品时,只需创建相应的产品类和创建者类即可,而不必修改现有代码。

工厂方法模式的具体应用场景

  • 创建复杂对象:当对象的创建过程较为复杂时,可以使用工厂方法模式将创建逻辑封装起来。
  • 不确定具体类型:当你事先不知道需要创建哪种类型的对象时,可以使用工厂方法模式,在运行时根据条件动态选择。
  • 代码重构:如果你发现代码中有大量的条件判断用来创建不同类型的对象,那么可以考虑使用工厂方法模式来重构代码,使其更加简洁和易于维护。
  • 框架开发:在开发框架时,工厂方法模式可以让框架用户通过继承来定制化对象的创建过程,而不需要修改框架本身的代码。

什么时候考虑使用工厂方法模式

  1. 当一个类不知道它所必须创建的对象的类时。
  2. 当一个类希望由它的子类来指定它所创建的对象时。
  3. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时。

工厂方法模式提供了一种有效的方式来解耦对象的创建与使用,使得系统更加灵活和易于扩展。对于那些需要根据条件动态创建不同类型对象的情况,工厂方法模式是一个非常有用的工具。理解如何正确使用工厂方法模式可以帮助开发者构建更加模块化和易于维护的软件系统。

http://www.lryc.cn/news/524465.html

相关文章:

  • 分布式搜索引擎02
  • 阿里云安装mikrotik7配置内网互通
  • Docker网段和服务器ip冲突导致无法访问网络的解决方法
  • Kubernetes 集群中安装和配置 Kubernetes Dashboard
  • Android开发之Spinner
  • 【c++继承篇】--继承之道:在C++的世界中编织血脉与传承
  • 分布式系统通信解决方案:Netty 与 Protobuf 高效应用
  • 计算机网络 (54)系统安全:防火墙与入侵检测
  • stack底层实现细节
  • 工业相机 SDK 二次开发-Halcon 插件
  • map和set的使用(一)详解
  • ARP 表、MAC 表、路由表、跨网段 ARP
  • 37.构造回文字符串问题|Marscode AI刷题
  • ssm-mybatisPlus学习笔记
  • 【算法学习笔记】35:扩展欧几里得算法求解线性同余方程
  • 线性规划:机器学习中的优化利器
  • Ubuntu开发中的问题
  • MAC 地址转换为标准大写格式
  • 使用插件SlideVerify实现滑块验证
  • 深入探索 Nginx 的高级用法:解锁 Web 服务器的强大潜能
  • (01)搭建开发环境
  • Win11桌面右键刷新选项在二级界面的修正方法
  • 配电室防静电地板通常用哪种
  • 【重庆市乡镇界】面图层shp格式arcgis数据乡镇名称和编码wgs84坐标无偏移内容测评
  • 68,[8] BUUCTF WEB [RoarCTF 2019]Simple Upload(未写完)
  • Windows电脑桌面记录日程安排的提醒软件
  • TiDB与Oracle:数据库之争,谁能更胜一筹?
  • USART_串口通讯中断案例(HAL库实现)
  • 【MySQL】存储引擎有哪些?区别是什么?
  • [OpenGL]实现屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)