07GoF之三种工厂模式

GoF(Gang of Four):四人组,《Design Patterns: Elements of Reusable Object-Oriented Software》(《设计模式》)的作者,设计了23种设计模式.但时代发展,还有其它的设计模式,比如:JavaEE的设计模式(DAO模式、MVC模式等)。
● GoF23种设计模式可分为三大类:
○ 创建型(5个):解决对象创建问题。
■ 单例模式
■ 工厂方法模式
■ 抽象工厂模式
■ 建造者模式
■ 原型模式
○ 结构型(7个):一些类或对象组合在一起的经典结构。
■ 代理模式
■ 装饰模式
■ 适配器模式
■ 组合模式
■ 享元模式
■ 外观模式
■ 桥接模式
○ 行为型(11个):解决类或对象之间的交互问题。
■ 策略模式
■ 模板方法模式
■ 责任链模式
■ 观察者模式
■ 迭代子模式
■ 命令模式
■ 备忘录模式
■ 状态模式
■ 访问者模式
■ 中介者模式
■ 解释器模式
● 工厂模式是解决对象创建问题的,所以工厂模式属于创建型设计模式。这里为什么学习工厂模式呢?这是因为Spring框架底层使用了大量的工厂模式。


为什么学工厂模式?
Spring底层就是通过工厂模式+XML+反射机制实现的.


工厂模式的三种形态
**● 第一种:简单工厂模式(Simple Factory):不属于23种设计模式之一。简单工厂模式又叫做:静态工厂方法模式。简单工厂模式是工厂方法模式的一种特殊实现。**一个工厂对应一种产品.
● 第二种:工厂方法模式(Factory Method):是23种设计模式之一。一个工厂对应多种产品.
● 第三种:抽象工厂模式(Abstract Factory):是23种设计模式之一。一个工厂对应多种产品系列.


简单工厂模式

Spring中的BeanFactory就使用了简单工厂模式。

简单工厂模式的角色包括三个:
● 工厂类 角色
● 抽象产品 角色
● 具体产品 角色

简单工厂模式的优点
● 客户端程序不需要关心对象的创建细节,需要哪个对象时,只需要向工厂索要即可,初步实现了责任的分离。客户端只负责“消费”,工厂负责“生产”。生产和消费分离。

简单工厂模式的缺点
● 缺点1:工厂类集中了所有产品的创造逻辑,形成一个无所不知的全能类,有人把它叫做上帝类。显然工厂类非常关键,不能出问题,一旦出问题,整个系统瘫痪。
● 缺点2:不符合OCP开闭原则,在进行系统扩展时,需要修改工厂类。

//抽象产品角色weapon
package com.sunsplanter.factory;
//抽象类无法被创建对象,无法实例化,是用来被子类继承的
//Tank和Weapon是is-a的关系
//且基本功能在不断变化(开炮/投弹),因此用抽象类
public abstract class Weapon {/*** 所有的武器都有攻击行为*/public abstract void attack();
}
//具体产品角色tank/Fighter
package com.sunsplanter.factory;public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
}```java
package com.sunsplanter.factory;public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
}
//工厂类角色
package com.sunsplanter.factory;public class WeaponFactory {/*** 根据不同的武器类型生产武器* @param weaponType 武器类型* @return 武器对象*/public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();}  else {throw new RuntimeException("不支持该武器!");}return weapon;}
}
package com.powernode.factory;public class Client {public static void main(String[] args) {Weapon weapon1 = WeaponFactory.get("TANK");weapon1.attack();Weapon weapon2 = WeaponFactory.get("FIGHTER");weapon2.attack();}
}

工厂方法模式

简单工厂违背了开闭原则,即每次扩展系统时,都要修改工厂类…工厂方法模式的将简单工厂模式的工厂类解耦为抽象工厂+具体工厂,每次扩展系统只要实现一次抽象工厂的接口就可以,不必修改原有程序.

工厂方法模式的角色包括:
● 抽象工厂角色
● 具体工厂角色

● 抽象产品角色
● 具体产品角色

工厂方法模式的优点
● 一个调用者想创建一个对象,只要知道其名称就可以了。
● 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
● 屏蔽产品的具体实现,调用者只关心产品的接口。
工厂方法模式的缺点
● 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

可以看到简单工厂和工厂方法的区别只在于:简单工厂模式的工厂类解耦为抽象工厂+具体工厂,他们的抽象产品角色和具体产品角色仍然是相同的.

//抽象产品角色
package com.sunsplanter.factory;public abstract class Weapon {/*** 所有武器都有攻击行为*/public abstract void attack();
}
//具体产品角色tank/Fighter
package com.sunsplanter.factory;public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
}```java
package com.sunsplanter.factory;public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
}
//抽象工厂角色(武器工厂接口)
package com.sunsplanter.factory;public interface WeaponFactory {Weapon get();
}
//具体工厂角色
package com.sunsplanter.factory;public class TankFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Tank();}
}
//具体工厂角色
package com.sunsplanter.factory;public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();}
}
package com.sunsplanter;public class Client {public static void main(String[] args) {TankFactory tankFactory = new TankFactory();//Weapon类型的gunTank tank = tankFactory.get();tank.attack();}
}

如果想扩展一个新的产品,只要新增一个产品类,再新增一个该产品对应的工厂即可,例如新增:匕首

//新增一个具体产品角色
package com.sunsplanter;public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍丫的!");}
}
//新增一个具体工厂角色
package com.sunsplanter;public class DaggerFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Dagger();}
}

抽象工厂模式

在工厂方法模式上再次进化,允许存在多个产品系列/工厂系列.

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

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

相关文章

VSCode安装GitHub Copilot插件方法

VSCode安装GitHub Copilot插件的步骤及注意事项如下: 安装步骤: 确保系统要求: 确保你正在使用的Visual Studio Code版本是最新的,且支持GitHub Copilot。同时,Copilot需要你的操作系统是Windows、macOS或Linux&#x…

如何通过PreMaint状态监测发现设备故障:以振动监测为例

在现代工业环境中,设备的健康状况对于维持生产效率至关重要。计划外停机可能导致巨大的成本损失,因此采用先进的监测技术成为预防性维护的核心策略之一。其中,振动监测作为一种早期故障检测手段,通过PreMaint状态监测系统的引入&a…

【前端面试题】每日一个前端面试专题

一、typeof 与 instanceof 区别?如何instanceof的原理 问题回答思路 typeof和instanceof 都可以检测数据类型,typeof检测如果是基本数据类型返回对应的结果。如果检测是对象的话,默认返回一个object,所以无法区分那种对象。 typeof 数据ins…

组件封装原则

在Vue中封装组件时,遵循低耦合、高内聚、可扩展性和可维护性的原则非常重要。以下是一些实现这些原则的关键点,并结合Vue的实践方式给出案例说明: 1. 单一职责原则: 每个组件专注于一个特定的功能或UI部分,例如&#…

Java动态代理机制,创建代理对象的方法(InvocationHandler,Proxy)

目录 1.什么是动态代理2.如何为Java对象创建一个代理对象 1.什么是动态代理 特点:无侵入式的给代码增加额外的功能。 在Java中,动态代理是一种机制,允许在运行时创建一个代理对象来代替原始对象,并可以在代理对象的方法执行前后追…

Hive操作命令上手手册

内容来自于《大数据Hive离线计算开发实战》 Hive原理 Hive是一个基于Hadoop的数据仓库和分析系统,用于管理和查询大型数据集。以下是Hive的原理: 数据仓库:Hive将结构化的数据文件映射成一张表,并提供类SQL查询功能。用户可以使…

第十五章 ECMAScript6新增的常用语法

文章目录 一、声明关键字二、箭头函数三、解构赋值四、展开运算符五、对字符的补充六、Symbol七、对象的简写语法八、Set和Map九、for-of 一、声明关键字 ES6新增的声明关键字: let,const:声明变量class:声明类import&#xff0c…

《网络是怎样连接的》2.5节图表(自用)

图5.1:ip包结构 图5.2:ip网络包的传输方式 1.以太网的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH等,它们都可以替代以太网的角色帮助IP协议来传输网络包 2.根据ARP协议,客户端可以根据ip地址得到下一个路…

最新最简操作系统期末复习(考前速过)

操作系统复习 第一章(操作系统引论)计算机操作系统包括:操作系统的目标:操作系统的作用:未配置操作系统的计算机系统:单道批处理系统:缺点: 多道批处理系统:优点&#xf…

国际版WPS Office18.6.0

​【应用名称】:WPS Office 【适用平台】:Android 【软件标签】:WPS 【应用版本】:18.5.4 → 18.6.0 【应用大小】:160MB 【软件说明】:WPS Office是使用人数最多的移动办公软件。它具有独有手机阅读…

TypeScript基础

ts学习 目录概述需求: 设计思路实现思路分析1.TypeScript 基础类型2.TypeScript 变量声明3.TypeScript 接口4.TypeScript 类5.TypeScript 函数5.TypeScript 泛型5.TypeScript 枚举TypeScript 类型推论TypeScript 类型兼容性TypeScript 高级类型TypeScript 迭代器和生…

读史笔记(二)

读史笔记(二) 考古是探求过去人类遗留的物质资料为手段,以研究人类发展进程及其规律为目的,为人们了解人类起源及相关的社会制度,宗教祭祀,生活习俗等提供了一种途径。而在我国,传统的金石学即源…

RoadMap8:C++中类的封装、继承、多态与构造函数

摘要:在本章中涉及C最核心的内容,本文以C中两种基础的衍生数据结构:结构体和类作为引子,从C的封装、继承与多态三大特性全面讲述如何在类这种数据结构进行体现。在封装中,我们讲解了类和结构体的相似性;在继…

自带恒压恒流环路的降压型单片车充专用芯片

一、基本概述 XL2009是一款高效降压型DC-DC转换器,固定180KHz开关频率,可以提供最高2.5A输出电流能力,具有低纹波,出色的线性调整率与负载调整率特点。XL2009内置固定频率振荡器与频率补偿电路,简化了电路设计。 PWM …

Java后端和前端传递的请求参数的三种类型

在 HTTP 请求中,常见的请求参数类型有三种:application/x-www-form-urlencoded、multipart/form-data 和 application/json(通常用于 raw 类型)。这三种类型主要指的是请求体中的数据格式,其中包括参数的传递方式和编码…

Docker(八)Python+旧版本chrome+selenium+oss2+fastapi镜像制作

目录 一、背景二、能力三、核心流程图四、制作镜像1.资源清单2.Dockerfile3.制作镜像 五、启动测试 一、背景 近几年我们线下的创业团队已从零到一开发过好几个小程序项目,都是和体育相关。其中生成海报分享图片好像都是不可或缺的功能。之前的项目老板给的时间都比…

从零学算法17

17.给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits “23” 输出:[…

【Spring】容器

注意点: p命名和c命名空间不能直接使用,需要导入xml约束! xmlns:p"http://www.springframework.org/schema/p" xmlns:c"http://www.springframework.org/schema/c"使用注解实现自动装配 jdk1.5 支持的注解,…

Java进击框架:Spring-Web(八)

Java进击框架:Spring-Web(八) 前言DispatcherServlet拦截器异常视图解析重定向转发 语言环境日志 过滤器带注释的控制器声明映射请求其它注解验证 功能性端点URI Links异步请求CORSHTTP缓存视图技术MVC配置其他Web框架 前言 Spring Web MVC是…

519基于单片机的自动切割流程控制系统

基于单片机的自动切割流程控制系统[proteus仿真] 自动切割流程控制系统这个题目算是课程设计和毕业设计中常见的题目了,本期是一个基于单片机的自动切割流程控制系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】,赞赏任意文章 2&…