使用工厂方法模式设计最佳实践

在前面的“设计模式”示例中,我们解释了当今常用的“工厂”模式。 在本节中,我们将了解具有更多抽象的更高级的解决方案。 该模式称为工厂方法设计模式。

定义:
Factory方法模式提供了一种用于创建对象的方法,但是将对象创建委托给了子类。 工厂方法设计模式以类似于工厂模式的方式解决了这些问题,并附加了抽象级别。

可以使用new关键字实例化该对象。 例如,对象A使用以下方法创建另一个对象B:

ClassB objB = new ClassB();

因此,对象A拥有对对象B的引用。

对象实例化对象实例化

由于如果后来修改了对象A,则对象A现在依赖于对象B,那么我们将不得不重新编译对象A。 对象的创建可能会更加复杂,如果存在更多的耦合,那么维护将是软件开发中一项痛苦而昂贵的工作。

为了避免这种最坏的情况,我们提供了新颖的设计模式来进行救援。 他们试图在客户端和对象创建者之间创建松散的耦合,并为开发人员提供其他一些设计优势。 工厂方法模式就是解决设计问题的一种模式。

常用:
工厂方法设计模式通常与装饰器设计模式一起用于各种框架(例如Struts,Spring,Apache)中。 有许多基于此Factory模式的J2EE模式,例如DAO模式。

让我们以服装工厂为例,我们正在创建各种类型的服装,但是客户完全不知道这些产品是如何创建的。 即使我们必须添加新的服装类型(例如夹克),也无需更改客户端代码,从而增加了应用程序的灵活性。

工厂模式类图

何时使用工厂方法模式?

  • 对象的创建需要代码的重用,而无需大量重复代码。
  • 一个类将不知道需要创建哪些子类。
  • 子类可以指定应创建的对象。
  • 父类会将对象的创建委托给其子类。

结构体

下图突出显示了工厂方法设计模式的典型结构。 与上述示例不同,已添加了一个附加的Factory Abstract(Factory)类。

工厂方法设计模式(UML)

在上图中,以下是参与者:

  • 产品:这为工厂方法创建的对象定义了一个接口。
  • 具体产品:实现产品接口。
  • 工厂(创建者):这是一个抽象类,定义了返回产品对象的工厂方法。
  • 具体工厂:此类实现并覆盖由父工厂类声明的方法。

客户(例如,对象类A)将要使用由ConcreteFactory类(对象类B)创建的产品。 但是,在这种情况下,客户端仅持有对接口B的引用,而不是对象“类B”,因此它不需要了解有关类B的任何信息。 实际上,可以有多个类可以实现抽象类。

Factory Method模式允许子类决定实例化哪个类的含义是什么?
从根本上讲,这意味着对工厂抽象类进行编码,而无需知道将实例化哪些实际的ConcreteProduct类,即它是Trouser还是Shirt。 这完全由ConcreteFactory类确定。

现在,将上述模式实现到我们的GarmentFactory示例中。

工厂方法示例

让我们开始吧。 我们不会重复在Factory Pattern文章中找到的具体产品的代码,例如Shirt.java和Trouser.java。

已创建一个面向客户的新Factory抽象类。

public abstract class Factory {protected abstract GarmentType createGarments(String selection);}

需要修改GarmentFactory类以继承抽象类Factory。

public class GarmentFactory extends Factory{public GarmentType createGarments(String selection) {if (selection.equalsIgnoreCase('Trouser')) {return new Trouser();} else if (selection.equalsIgnoreCase('Shirt')) {return new Shirt();}throw new IllegalArgumentException('Selection doesnot exist');}
}

客户端类引用Factory类,并对Factory的createGarments(selection)方法进行分类以在运行时创建产品。

Factory factory = new GarmentFactory();
GarmentType objGarmentType = factory.createGarments(selection);
System.out.println(objGarmentType.print());


优点:

  • 通过将对象创建从客户端代码移到Factory类及其子类,代码可以灵活,松耦合和可重用。 由于异议创建是集中的,因此维护此类代码更加容易。
  • 客户代码仅处理产品接口,因此无需修改客户代码逻辑即可添加任何具体产品。
  • Factory Method的优点是它可以多次返回相同的实例,或者可以返回子类而不是该确切类型的对象。
  • 它通过在工厂中创建对象来鼓励代码的一致性,该工厂强制执行每个人都必须遵循的一组明确的规则。 这样可以避免在不同的客户端使用不同的构造函数。


例:

JDBC是这种模式的一个很好的例子。 应用程序代码不需要知道将与哪个数据库一起使用,因此不需要知道应使用哪些特定于数据库的驱动程序类。 相反,它使用工厂方法来获取连接,语句和其他可使用的对象。 这提供了更改后端数据库的灵活性,而无需更改您的DAO层。
以下是SDK中的一些示例:
valueOf()方法,返回由工厂创建的对象,该对象与传递的参数值相等。 getInstance()方法,该方法创建Singleton类的实例。 newInstance()方法,该方法用于每次调用时从工厂方法创建和返回新实例。 下载示例代码

参考: Idiotechie博客上来自JCG合作伙伴 Mainak Goswami的使用Factory Method Pattern设计最佳实践 。

翻译自: https://www.javacodegeeks.com/2012/10/design-best-practices-using-factory-method-pattern.html

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

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

相关文章

qt绘制一圈圆_Qt绘制圆

最近开始折腾Qt了,手头上的一个项目需要用到Qt来绘制一些简单图像。记录下Qt绘制圆的过程:对于以A为圆心,半径为R的圆,外部有一个外切的正方形,正方形上有B点。如下图所示:对于void QPainter::drawArc(int …

前端基础之HTML

HTML介绍 Web服务本质 import socketsk socket.socket()sk.bind(("127.0.0.1", 8080)) sk.listen(5)while True:conn, addr sk.accept()data conn.recv(8096)conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.secd(b"<h1>Hello world!</h1&g…

指令引用了 内存 该内存不能为read 一直弹窗_【翻译】使用Rust测试ARM和X86内存模型

原文标题: The Story of Tail Call Optimizations in Rust 原文标题: Examining ARM vs X86 Memory Models with Rust原文链接: https://www.nickwilcox.com/blog/arm_vs_x86_memory_model/公众号&#xff1a; Rust碎碎念苹果公司最近宣布&#xff0c;他们将要把笔记本和桌面电…

npm升级依赖包_Taro跨端开发之依赖管理

昨天跑的好好项目,今天跑不起来我们在开发周期比较长的前端项目的时候,必然会遇到依赖管理的问题. 我们在开发项目的时候,我们用了大量的三方库.这些三方的依赖库时不时的会更新自己的代码.第三方依赖库的代码更新会很容易造成代码运行的不稳定, 比如昨天还跑的好好的项目,另一…

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

java 布隆过滤器_什么是布隆过滤器(Bloom Filter)?

在日常工作中&#xff0c;有一个比较常见的需求&#xff0c;就是需要判断一个元素是否在集合中。例如以下场景&#xff1a;给定一个IP黑名单库&#xff0c;检查指定IP是否在黑名单中&#xff1f;在接收邮件的时候&#xff0c;判断一个邮箱地址是否为垃圾邮件&#xff1f;在文字…

STM32上使用JSON

一、STM32工程中添加JSON 最近在一网2串项目&#xff0c;串口和网口之间可能需要定义一下简单的通信协议&#xff0c;而通信协议上则需要去定义一下通信的数据格式&#xff0c;上次听剑锋说要用Json来定义&#xff0c;目前查了下资料具体如何去应用还不 会。因为最新的KEIL上支…

Flex 学习

Flex案例一&#xff1a; 1 <html>2 <head>3 <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> 4 <title>无标题</title>5 <style type"text/css">6 body,h1,h2,h3,h4,…

Cocos2d-X中实现自己定义菜单处理事件

当用户点击再松开后才会响应菜单事件&#xff0c;而在游戏中有些游戏须要玩家点击后就处理事件。如玩坦克大战的时候&#xff0c;玩家是点击一下就发射子弹。并是点击松手后发射子弹&#xff0c;在Cocos2d-X中没有这样的消息。以下就通过自己定义的方式实现当用户点击后就调用处…

java linkedhashset_java之LinkedHashSet

LinkedHashSet是Set集合的一个实现&#xff0c;具有set集合不重复的特点&#xff0c;同时具有可预测的迭代顺序&#xff0c;也就是我们插入的顺序。并且linkedHashSet是一个非线程安全的集合。如果有多个线程同时访问当前linkedhashset集合容器&#xff0c;并且有一个线程对当前…

Jmeter 场景设计

今天的业务场景是&#xff1a; 1.管理员登录后台---登录成功后添加一个某类型的产品---产品添加成功后&#xff0c;再为该产品添加10个排期。 2.管理员登录后台--登录成功后添加多个不同类型产品---产品全部添加完成后&#xff0c;依次为所有产品添加10个排期。 这是两种不同的…

Android IPC机制(五)用Socket实现跨进程聊天程序

1.Socket简介 Socket也称作“套接字“&#xff0c;是在应用层和传输层之间的一个抽象层&#xff0c;它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。它分为流式套接字和数据包套接字&#xff0c;分别对应网络传输控制层的TCP和UDP协议。TCP协…

java获取byte 长度_java获取字节的长度.

我们经常要获取中文,数字,或者英文字符所占字节的长度,下面就列出各种编码格式下所占字节的长度:代码如下:package pack.java.midea.dao;import java.io.UnsupportedEncodingException;/*** 测试;* author zhouhaitao* 2012-5-17*/public class Test {/*** param args* throws …

Batoo JPA –比领先的JPA提供商快15倍

介绍 我早在2000年代就喜欢JPA 1.0。 我甚至在稳定版本发布之前就将其与EJB 3.0一起使用。 我非常喜欢它&#xff0c;因此我为JBoss 3.x实现贡献了一些零碎的部分。 那时我们公司规模还很小。 创建新功能和应用程序比性能更重要&#xff0c;因为我们有很多想法&#xff0c;我…

python软件是哪个国家的品牌_有哪些好用的软件被国人误认为是外国研发的?

国产软件被标榜上了英文&#xff0c;即便不是英文&#xff0c;用拼音写出来&#xff0c;也会有人误认为是国外的软件。因为这样可以显得高大上&#xff0c;为什么我们会有这样的想法&#xff0c;是崇洋媚外吗&#xff0c;并不是&#xff0c;而是之前的国产软件的确有不少让我们…

postgres 支持的线程数_线程池被打满了怎么处理呢,你是否真的了解线程池?

0、前言线程池&#xff0c;顾名思义就是线程的池子&#xff0c;在每次需要取线程去执行任务的时候&#xff0c;没必要每次都创建新线程执行&#xff0c;线程池就是起着维护线程的作用&#xff0c;当有任务的时候就取出一个线程执行&#xff0c;如果任务执行完成则把线程放回到池…

[树形DP]没有上司的舞会

题目链接 思考 首先本题中的关系是一种树形结构&#xff0c;而且符号最优子结构和无后效性&#xff0c;所以可以进行记忆化搜索。 那么首先要在这颗树中选出一个点作为根节点&#xff0c;按照习惯我们将没有父节点的点作为根节点。 接下来要思考的是 状态&#xff1a; dp[i][0…

mybatis通用mapper_全网最全Mapper解析,附实操代码帮你更好理解

今天给大家介绍一位老朋友当你第一次接触Java开发的时候&#xff0c;这个老朋友就和你形影不离&#xff0c;当你要进行ORM的时候&#xff0c;单表的增删改查&#xff0c;这位老朋友给了你极大的帮助&#xff0c;不知道你想到他了吗&#xff1f;对&#xff0c;这就是通用mapper&…

初尝微信小程序2-基本框架

基本框架&#xff1a; .wxml &#xff1a;页面骨架 .wxss &#xff1a;页面样式 .js &#xff1a;页面逻辑 描述一些行为 .json &#xff1a;页面配置 创建一个小程序之后&#xff0c;app.js,app.json,app.wxss是必须的&#xff0c;而且名字也不能随意更改&#xff0c;…

洛谷 P1795 无穷的序列_NOI导刊2010提高(05)

P1795 无穷的序列_NOI导刊2010提高&#xff08;05&#xff09; 题目描述 有一个无穷序列如下&#xff1a; 110100100010000100000… 请你找出这个无穷序列中指定位置上的数字 输入输出格式 输入格式&#xff1a;第一行一个正整数N&#xff0c;表示询问次数&#xff1b; 接下来的…