抽象工厂模式与工厂方法(简单工厂)的区别

在软件开发中,简单工厂模式和工厂方法模式是两种常用的创建型设计模式。尽管它们都用于创建对象,但它们的实现方式和应用场景有所不同。本文将详细探讨这两种模式的区别,帮助你更好地理解和应用它们。

简单工厂模式

简单工厂模式,又称静态工厂方法模式,它通过一个工厂类的静态方法,根据传入的参数来决定创建哪一种产品对象。

简单工厂模式的结构
  1. 工厂类(Factory Class):包含一个静态方法,根据传入的参数决定实例化哪个具体类。
  2. 产品类(Product Classes):具体的产品类实现相同的接口或继承相同的抽象类。
  3. 客户端(Client):通过调用工厂类的静态方法来获取产品对象,而不是直接创建对象。
简单工厂模式的示例
// 产品接口
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 class ShapeFactory {public static Shape createShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}
}// 客户端
public class Client {public static void main(String[] args) {Shape shape1 = ShapeFactory.createShape("CIRCLE");shape1.draw();Shape shape2 = ShapeFactory.createShape("RECTANGLE");shape2.draw();}
}

 

工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。它使一个类的实例化延迟到其子类。

工厂方法模式的结构
  1. 抽象工厂类(Abstract Factory Class):定义一个抽象的工厂方法,让子类实现这个方法来创建产品对象。
  2. 具体工厂类(Concrete Factory Classes):实现抽象工厂类的工厂方法,实例化具体的产品对象。
  3. 产品类(Product Classes):具体的产品类实现相同的接口或继承相同的抽象类。
  4. 客户端(Client):通过调用具体工厂类的工厂方法来获取产品对象,而不是直接创建对象。
工厂方法模式的示例
// 产品接口
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 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();Shape shape1 = circleFactory.createShape();shape1.draw();ShapeFactory rectangleFactory = new RectangleFactory();Shape shape2 = rectangleFactory.createShape();shape2.draw();}
}
区别
  1. 复杂度

    • 简单工厂模式:实现简单,只需要一个工厂类的静态方法。适用于产品种类较少、变化不频繁的情况。
    • 工厂方法模式:结构复杂,需要定义抽象工厂类和多个具体工厂类。适用于产品种类较多、经常变化的情况。
  2. 扩展性

    • 简单工厂模式:不符合开闭原则(Open/Closed Principle),每次添加新产品都需要修改工厂类的代码。
    • 工厂方法模式:符合开闭原则,添加新产品时只需添加新的具体工厂类,不需要修改现有代码。
  3. 灵活性

    • 简单工厂模式:客户端代码依赖于工厂类的静态方法,灵活性较差。
    • 工厂方法模式:通过多态性实现,客户端代码可以动态选择使用哪个具体工厂类,灵活性更高。
选择哪种模式?
  • 如果产品种类较少且变化不频繁,可以使用简单工厂模式,因为它实现简单且直观。
  • 如果产品种类较多且经常变化,建议使用工厂方法模式,因为它具有更好的扩展性和灵活性。

抽象工厂模式与工厂方法模式的区别

在软件设计中,工厂方法模式(Factory Method Pattern)和抽象工厂模式(Abstract Factory Pattern)都是创建型设计模式,它们都用于创建对象,但它们的实现方式和应用场景有所不同。本文将详细探讨这两种模式的区别,帮助你更好地理解和应用它们。

工厂方法模式

工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪一个类。这样,工厂方法模式让类的实例化延迟到子类。

工厂方法模式的结构
  1. 抽象产品类(Abstract Product Class):定义产品的接口。
  2. 具体产品类(Concrete Product Classes):实现抽象产品接口。
  3. 抽象工厂类(Abstract Factory Class):定义一个创建产品对象的抽象方法。
  4. 具体工厂类(Concrete Factory Classes):实现抽象工厂类,具体化创建产品对象的方法。
示例
// 抽象产品接口
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 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();Shape shape1 = circleFactory.createShape();shape1.draw();ShapeFactory rectangleFactory = new RectangleFactory();Shape shape2 = rectangleFactory.createShape();shape2.draw();}
}
抽象工厂模式

抽象工厂模式提供一个接口,用于创建一系列相关或依赖对象的家族,而无需指定具体类。

关键在于客户端代码使用工厂时不需要关心具体的工厂和产品类是什么,而是通过工厂接口或抽象类来创建产品

抽象工厂模式的结构
  1. 抽象产品类(Abstract Product Classes):定义不同产品的接口。
  2. 具体产品类(Concrete Product Classes):实现抽象产品接口。
  3. 抽象工厂类(Abstract Factory Class):定义创建一组相关或依赖对象的接口。
  4. 具体工厂类(Concrete Factory Classes):实现抽象工厂接口,具体化创建一组相关或依赖对象的方法。
示例
// 抽象产品接口
public interface Shape {void draw();
}public interface Color {void fill();
}// 具体产品类
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 class Red implements Color {@Overridepublic void fill() {System.out.println("Filling with Red");}
}public class Blue implements Color {@Overridepublic void fill() {System.out.println("Filling with Blue");}
}// 抽象工厂接口
public interface AbstractFactory {Shape createShape(String shapeType);Color createColor(String colorType);
}// 具体工厂类
public class ShapeFactory implements AbstractFactory {@Overridepublic Shape createShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}@Overridepublic Color createColor(String colorType) {return null; // ShapeFactory 不负责创建颜色对象}
}public class ColorFactory implements AbstractFactory {@Overridepublic Shape createShape(String shapeType) {return null; // ColorFactory 不负责创建形状对象}@Overridepublic Color createColor(String colorType) {if (colorType == null) {return null;}if (colorType.equalsIgnoreCase("RED")) {return new Red();} else if (colorType.equalsIgnoreCase("BLUE")) {return new Blue();}return null;}
}// 客户端
public class Client {public static void main(String[] args) {AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");Shape shape1 = shapeFactory.createShape("CIRCLE");shape1.draw();Shape shape2 = shapeFactory.createShape("RECTANGLE");shape2.draw();AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");Color color1 = colorFactory.createColor("RED");color1.fill();Color color2 = colorFactory.createColor("BLUE");color2.fill();}
}// 工厂生成器类
public class FactoryProducer {public static AbstractFactory getFactory(String choice) {if (choice.equalsIgnoreCase("SHAPE")) {return new ShapeFactory();} else if (choice.equalsIgnoreCase("COLOR")) {return new ColorFactory();}return null;}
}
工厂方法模式与抽象工厂模式的区别
  1. 产品维度

    • 工厂方法模式:关注的是单一产品对象的创建,适用于创建单一产品的场景。
    • 抽象工厂模式:关注的是一组相关或互相依赖的产品对象的创建,适用于创建产品族的场景。
  2. 工厂接口的复杂度

    • 工厂方法模式:工厂接口只包含一个创建方法,负责创建一种产品对象。
    • 抽象工厂模式:工厂接口包含多个创建方法,每个方法负责创建一种产品对象。
  3. 扩展性

    • 工厂方法模式:扩展新的产品时,只需增加新的具体工厂类,但扩展产品族会涉及较多修改。
    • 抽象工厂模式:扩展新的产品族时,只需增加新的具体工厂类,无需修改现有代码,但扩展新的产品种类时,可能需要修改抽象工厂接口及其所有实现类。
  4. 应用场景

    • 工厂方法模式:适用于产品类型单一,且产品类的创建有较复杂的逻辑或要求延迟到子类的情况。
    • 抽象工厂模式:适用于需要创建一组相关或互相依赖的产品对象,且需要保证这些对象的一致性的情况。
总结

工厂方法模式和抽象工厂模式都是用于创建对象的设计模式,但它们在复杂度和应用场景上有所不同。工厂方法模式适用于单一产品的创建,而抽象工厂模式适用于创建一组相关的产品对象。在实际开发中,选择合适的模式可以提高代码的灵活性和可维护性。希望通过这篇文章,你能更好地理解这两种模式,并在合适的场景中应用它们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昇思25天学习打卡营第11天|RNN实现情感分类

概述 情感分类是自然语言处理中的经典任务,是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型,实现如下的效果: 输入: This film is terrible 正确标签: Negative 预测标签: Negative输入: This film is great 正确标…

Mongodb复合索引

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第90篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

【计算机毕业设计】002基于weixin小程序家庭记账本

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

【实战:python-Django发送邮件-短信-钉钉通知】

一 Python发送邮件 1.1 使用SMTP模块发送邮件 import smtplib from email.mime.text import MIMEText from email.header import Headermsg_from 306334678qq.com # 发送方邮箱 passwd luzdikipwhjjbibf # 填入发送方邮箱的授权码(填入自己的授权码,相当于邮箱…

鸿蒙语言基础类库:【@ohos.uitest (UiTest)】 测试

UiTest UiTest提供模拟UI操作的能力,供开发者在测试场景使用,主要支持如点击、双击、长按、滑动等UI操作能力。 该模块提供以下功能: [By]:提供控件特征描述能力,用于控件筛选匹配查找。[UiComponent]:代…

实验四:图像的锐化处理

目录 一、实验目的 二、实验原理 1. 拉普拉斯算子 2. Sobel算子 3. 模板大小对滤波的影响 三、实验内容 四、源程序和结果 (1) 主程序(matlab) (2) 函数GrayscaleFilter (3) 函数MatrixAbs 五、结果分析 1. 拉普拉斯滤波 2. Sobel滤波 3. 不同大小模板的滤波…

单点登陆思路及流程

单点登录(Single Sign-On,简称SSO)是一种流行的身份验证和授权机制,允许用户通过一次登录获得对多个应用程序或系统的访问权限。实现单点登录可以提高用户体验、简化用户管理和减少密码重复输入等问题。下面是一种常见的单点登录实…

昇思25天学习打卡营第7天 | 基于MindSpore的GPT2文本摘要

本次打卡基于gpt2的文本摘要 数据加载及预处理 from mindnlp.utils import http_get# download dataset url https://download.mindspore.cn/toolkits/mindnlp/dataset/text_generation/nlpcc2017/train_with_summ.txt path http_get(url, ./)from mindspore.dataset impor…

以太坊(以太坊solidity合约)

以太坊(以太坊solidity合约) 1,以太坊2,开发名词解释(1)钱包(2)Solidity(3)Ether(以太币)(4)Truffle&#xff…

Redis 7.x 系列【23】哨兵模式

有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 工作原理2.1 监控2.2 标记下线2.3 哨兵领袖2.4 新的主节点2.5 通知更新 3. …

请求响应(后端必备)

一、请求 1.简单参数 原始方式: 在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取 RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request){String name request.getP…

什么叫价内期权?直接带你了解期权价内期权怎么使用?!

今天带你了解什么叫价内期权?直接带你了解期权价内期权怎么使用?!价内期权是具有内在价值的期权。期权持有人行权时,对看涨期权而言,行权价格低于标的证券结算价格;对看跌期权而言,标的证券结算…

js 请求blob:https:// 图片

方式1 def get_file_content_chrome(driver, uri):result driver.execute_async_script("""var uri arguments[0];var callback arguments[1];var toBase64 function(buffer){for(var r,nnew Uint8Array(buffer),tn.length,anew Uint8Array(4*Math.ceil(t/…

前端Vue组件化实践:自定义加载组件的探索与应用

在前端开发领域,随着业务逻辑复杂度的提升和系统规模的不断扩大,传统的开发方式逐渐暴露出效率低下、维护困难等问题。为了解决这些挑战,组件化开发作为一种高效、灵活的开发模式,受到了越来越多开发者的青睐。本文将结合实践&…

Java基础及进阶

JAVA特性 基础语法 一、Java程序的命令行工具 二、final、finally、finalize 三、继承 class 父类 { //代码 }class 子类 extends 父类 { //代码 }四、Vector、ArrayList、LinkedList 五、原始数据类型和包装类 六、接口和抽象类 JAVA进阶 Java引用队列 Object counter ne…

PostgreSQL行级安全策略探究

前言 最近和朋友讨论oracle行级安全策略(VPD)时,查看了下官方文档,看起来VPD的原理是针对应用了Oracle行级安全策略的表、视图或同义词发出的 SQL 语句动态添加where子句。通俗理解就是将行级安全策略动态添加为where 条件。那么PG中的行级安全策略是怎…

搭建基于 ChatGPT 的问答系统

搭建基于 ChatGPT 的问答系统 📣1.简介📣2.语言模型,提问范式和 token✨2.1语言模型✨2.2Tokens✨2.3Helper function辅助函数(提问范式) 📣3.评估输入-分类📣4.检查输入-审核✨4.1审核4.1.1 我…

使用UDP通信接收与发送Mavlink2.0协议心跳包完整示例

1.克隆mavlink源码 https://github.com/mavlink/mavlink.git 2.进入mavlink目录,安装依赖 python3 -m pip install -r pymavlink/requirements.txt 3.生成Mavlink的C头文件 mavlink % python3 -m pymavlink.tools.mavgen --lang=C --wire-protocol=2.0 --output=generated…

1-5岁幼儿胼胝体的表面形态测量

摘要 胼胝体(CC)是大脑中的一个大型白质纤维束,它参与各种认知、感觉和运动过程。尽管CC与多种发育和精神疾病有关,但关于这一结构的正常发育(特别是在幼儿阶段)还有很多待解开的谜团。虽然早期文献中报道了性别二态性,但这些研究的观察结果…