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

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

定义:
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,一经查实,立即删除!

相关文章

偏导数

引入 一元函数导数: 在一元函数中,我们已经知道导数就是函数的变化率(对于一个一元函数,x增大了多少,y增大了多少,这个就是变化率)。对于二元函数我们同样要研究它的“变化率”。在xOy平面内&am…

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;他们将要把笔记本和桌面电…

Docker应用二:docker常用命令介绍

Docker常用命令使用介绍 docker中常用的命令: 1、docker search image_name:搜查镜像 2、docker pull image_name:从镜像库中拉去镜像 3、docker run image_name:运行容器 --restartalways:容器退出后重新启动 --name:自定容器名字 --d:后台运行容器 --i:交互模式 --t:打开一个…

关于Ubuntu使用笔记

Ubuntu vm tools 安装 sudo apt install open-vm-tools-desktop 在安装程序时Ubuntu会将安装目录锁定&#xff0c;安装结束后会解除锁定&#xff0c;中断安装后无法再安装其他软件解决方案 E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavail…

具有可执行Tomcat的独立Web应用程序

在部署应用程序时&#xff0c;简单性是最大的优势。 您将了解到&#xff0c;尤其是在项目发展且需要在环境中进行某些更改时。 将整个应用程序打包到一个独立且自足的JAR中似乎是个好主意&#xff0c;尤其是与在目标环境中安装和升级Tomcat相比。 过去&#xff0c;我通常将Tomc…

css网页中设置背景图片的方法详解

在css代码中设置背景图片的方法&#xff0c;包括背景图片、背景重复、背景固定、背景定位等 用css设置网页中的背景图片&#xff0c;主要有如下几个属性&#xff1a; 1&#xff0c;背景颜色 {">说明&#xff1a;参数取值和颜色属性一样 注意&#xff1a;在HTML当中&am…

node-sass安装不成功的问题

SASS_BINARY_SITEhttps://npm.taobao.org/mirrors/node-sass/ npm install node-sass 简单粗暴的执行上述的命令。转载于:https://www.cnblogs.com/czaiz/p/6918114.html

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

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

QOTD:Java线程与Java堆空间

以下问题很常见&#xff0c;并且与OutOfMemoryError有关&#xff1a;在JVM线程创建过程和JVM线程容量期间无法创建新的本机线程问题。 这也是我向新技术候选人&#xff08;高级职位&#xff09;提出的典型面试问题。 我建议您在查看答案之前尝试提供自己的答复。 题&#xff1…

sql查询重复项

select * from [表A] where id in (select id from [表A] group by id having count(id) >1 )转载于:https://www.cnblogs.com/wuyujie/p/7885017.html

java util logging_简单日志记录,使用java.util.logging

jspservletJavaBean模式下,可以做个简单的日志记录,日志文件保存在服务器.(Tomcat)package controller;import java.io.File;import java.io.IOException;import java.util.logging.FileHandler;import java.util.logging.Level;import java.util.logging.Logger;import javax.…

超级高铁

超级高铁 作者&#xff1a;武培&#xff0c;高培焱 作品来源&#xff1a;实践 美国电动汽车公司特斯拉和美国科技公司ET3都公布了“真空管钢运输”计划&#xff0c;特斯拉将其命名为“超级高铁”&#xff0c;ET3因列车外观酷似胶囊因而称之为“吃胶囊”列车。根据ET3公司的介绍…

使用Spring @Autowired List的责任链

在Spring 3.1中&#xff0c;有一种方法可以自动填充类型化的List&#xff0c;这在您想在代码中稍微进行去耦和清理时非常方便。 为了向您展示它是如何工作的&#xff0c;我将实现一个简单的责任链&#xff0c;该责任链将为通过的用户打印一些问候。 让我们从我们拥有的&#…

设计模式 建造者模式 与 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中没有这样的消息。以下就通过自己定义的方式实现当用户点击后就调用处…