前言
在上文提到的简单工厂模式中,发现简单工厂模式存在一系列问题:
工厂类集中了所有产品的创建逻辑,一旦这个工厂类不能正常工作,整个系统都会受到巨大的影响。
违背开闭原则。一旦添加新产品时,不是通过新增类解决,而是通过修改原先的工厂类逻辑来解决。这样会造成工厂类静态工厂方法逻辑过于复杂。
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
为了解决上述的问题,我们又使用了一种新的设计模式:工厂方法模式
工厂方法模式的定义
工厂方法模式,又称工厂模式、多态工厂模式。通过定义父类工厂负责定义创建对象的公共接口,而子类则负责生成具体的对象。
工厂方法模式的作用
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成。(简单工厂模式中,是将具体产品的创建延迟到具体产品子类中去创建)既由具体工厂来决定应该实例话哪一种产品。
工厂模式方法将具体产品的创建过程延迟到工厂类的子类中。此时工厂类不再负责所有产品的创建逻辑。而是仅仅给出具体工厂必须实现的接口。这样在新增产品的时候。就不需要更改抽象工厂类。而是只需要新增新的工厂实现子类就可以了。符合了开闭原则。克服了简单工厂模式的缺点
工厂模式的UML
工厂模式使用步骤
创建抽象工厂类,定义具体工厂的公共接口
创建抽象产品类,定义具体产品的公共接口
创建具体产品类,定义生产的具体产品
创建具体接口类,重写抽象工厂类的公共接口来创建不同的具体产品类
外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
工厂方法模式优点
更符合开闭原则。新增一种产品时,只需要添加相应的具体产品类和相应的工厂子类即可。而简单工厂模式需要修改工厂类的判断逻辑
符合单一职责原则,每个具体工厂类只负责创建对应的产品。而简单工厂模式中的工厂类存在复杂的switch-case 或者 if-else逻辑判断
不使用静态工厂方法,可以形成基于继承的等级结构。而简单工厂模式中的工厂类使用的是静态工厂方法。
工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
工厂方法模式的应用常见场景
在一个类不知道他所需要的对象的类时。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可。
当一个类希望通过其子类来制定创建对象时。在工厂方法模式中,抽象工厂类只需要提供一个创建产品的接口,返回的抽象产品父类。而由其子类来确定要创建的具体产品对象。多态,易拓展。
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类。需要时再动态指定,可将具体工厂类的类名存在在配置文件或者数据库中。通过反射中的newInstance创建对象。
工厂方法模式的缺点
添加一个新产品就得添加一个具体的工厂类。系统类的个数将成对增加。一定程度上增加了系统的复杂度和开销
一个具体工厂只能创建一种具体产品
代码实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package com.dding.pmsmigrateServer.test; //客户端 public class Test { public static void main(String[] args) { } } //定义抽象工厂 interface AbstractFactory{ AbstractProduct getProduct(); } //定义抽象产品类 interface AbstractProduct{ void show(); } //定义具体产品子类apple class Apple implements AbstractProduct{ public void show(){ System.out.println( "apple" ); } } //定义具体产品子类monce class Mouce implements AbstractProduct{ public void show(){ System.out.println( "monce" ); } } //定义具体的产品子类cat class Cat implements AbstractProduct{ public void show(){ System.out.println( "cat" ); } } //定义生产apple的工厂子类 class AppleFactory implements AbstractFactory{ public AbstractProduct getProduct(){ return new Apple(); } } //定义生产mouce的工厂子类 class MonceFactory implements AbstractFactory{ public AbstractProduct getProduct(){ return new Mouce(); } } <br> |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· C# 13 中的新增功能实操
· Supergateway:MCP服务器的远程调试与集成工具