Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

工厂模式:


工厂模式可以分为三类:

1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)


简单工厂模式

插头 分为二孔插头和三孔插头。
首先 创建插头产品类 Pin

public class Pin {protected String PinType;
}

然后分别创建二孔插头和三孔插头类

/**
* @author hjn
*二孔插头类
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}/**
* @author hjn
*三孔插头类
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}
public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");} }

然后创建插头工厂类

/**
* @author hjn
*插头工厂类
*/
public class PinFactory {/*** @param type* @return* 根据插头数返回相对的插头对象*/public static Pin creatPin(int type) {switch (type) {case 2:return new PinTw();case 3:return new PinTh();default:break;}return null;}
}

最后 测试类 :

public class TestPin {public static void main(String[] args) {Pin pinth = PinFactory.creatPin(3);Pin pintw = PinFactory.creatPin(2);}
}        

 

这就是简单工厂模式。

简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。
先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。

下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的插头型号的时候,想要一种更多头的新型插头,只要这种插头符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型插头,都要在工厂类中增加相应的创建业务逻辑(creatPin(int type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。
我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员。
于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的插头种类型,就增加该插头种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。

简单工厂模式的优缺点
 优点:客户端不需要修改代码。
 缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。


工厂方法模式

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
工厂方法模式组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!

首先 创建插头产品类 Pin

public class Pin {protected String PinType;
}

 

然后分别创建二孔插头和三孔插头类

/**
* @author hjn
*二孔插头类
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}/**
* @author hjn
*三孔插头类
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");}
}

然后创建插头工厂接口:

/**
* @author hjn
* 工厂方法接口*
*/
public interface IPinFactory {public Pin creatPin();}

然后创建 二孔插头和三孔插头的工厂

 

/**
* @author hjn
*二孔的工厂类 
*/
public class PinTwFactory implements IPinFactory {Pin ptw=new PinTw();public Pin creatPin() {    return ptw;}
}/**
* @author hjn
*三孔的工厂类
*/
public class PinThFactory implements IPinFactory {Pin pth=new PinTh();public Pin creatPin() {    return pth;}
}

 

测试类 :

 

public class TestPin {public static void main(String[] args) {PinThFactory pthf =new PinThFactory();Pin pinth = pthf.creatPin();PinTwFactory ptwf=new PinTwFactory();Pin pintw = ptwf.creatPin();}
}

 

这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂,当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。

  好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。
  缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。


抽象工厂模式

首先 创建插头产品类 Pin

public class Pin {protected String PinType;
}

然后分别创建二孔插头和三孔插头类

/**
* @author hjn
*二孔插头类
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}
 
/**
* @author hjn
*三孔插头类
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");}
}

 


然后创建插头工厂接口:

/**
* @author hjn
* 工厂方法接口*
*/
public interface IPinFactory {public Pin creatPinTw();public Pin creatPinTh();
} /**
* @author hjn
*Pin工厂实现类
*/
public class PinFactoryImpl implements IPinFactory {@Overridepublic Pin creatPinTw() {return new PinTw();}@Overridepublic Pin creatPinTh() {    return new PinTh();}}

 

测试类

public class TestPin {public static void main(String[] args) {PinFactoryImpl pin = new PinFactoryImpl();Pin ptw = pin.creatPinTw();Pin pth = pin.creatPinTh();}
}

 

 抽象工厂模式,一个具体工厂可以制造几个产品

优点:易于交换产品系列,例如Access和SQLServer数据库之间切换。
  缺点:如果需要增加新的产品树,那么就要新增三个产品类,并且要修改三个工厂类。这样大批量的改动是很丑陋的做法。


工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。


区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

转载于:https://www.cnblogs.com/caixiaohua/p/6760389.html

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

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

相关文章

今天很多 CTO 都是被干掉的,因为他没有成就业务

作者|乔新亮 编辑|邓艳琴 我可以丝毫不开玩笑地说,今天,很多传统企业里的研发都只是“工人”,哪怕是 CTO,充其量也只是“高级工人”,如果不转换思维去成就业务,就只能停留在工人级…

中航工业集团金网络(北京)电子商务有限公司副总经理刘正珩:航空“智”造的供应链支撑平台...

编者按 “十三五”时期是我国贸易发展的重要战略机遇期,物流产业发展迅速,智慧供应链已经成为推动流通大国向流通强国过程中的重要行动。6月2日,由上海市国有资产监督管理委员会、上海市邮政管理局、上海市商务委员会指导,上海市国…

创建、检查和反编译世界上(几乎)最短的 C# 程序

创建、检查和反编译世界上(几乎)最短的 C# 程序原文来自https://www.stevejgordon.co.uk/creating-inspecting-decompiling-the-worlds-smallest-csharp-program在这篇文章中,我认为创建世界上(几乎)最短的 C# 程序然后…

Linux下画原理图和PCB

Linux下画原理图和PCBWindows下大名鼎鼎的Allegro和经典的Protel 99SE都是不支持Linux操作系统的。做Linux驱动开发免不了要看一下原理图和PCB。一般的做法有三种: 1.主机使用Windows系统,将Linux装在VMWARE之类的虚拟机中这样能够使用Windows下的软件看…

配置中心 App Configuration (二):Feature Flag 功能开关特性

写在前面Web服务开发过程中我们经常有这样的需求:某些功能我必须我修改了配置才启用,比如新用户注册送券等;某个功能需到特定的时间才启用,过后就失效,比如春节活动等;某些功能,我想先对10%的用…

oracle临时表空间

--查看临时表空间SELECT * FROM v$tablespace;SELECT * FROM dba_tablespaces;--查看所有临时表空间文件SELECT * FROM dba_data_files;--查看临时临时表空间文件SELECT * FROM dba_temp_files;--查看临时表空间组SELECT * FROM dba_tablespace_groups; --查找默认临时表空间SE…

ES 2022 正式发布!有哪些新特性?

2022 年 6 月 22 日,第 123 届 Ecma 大会批准了 ECMAScript 2022 语言规范[1],这意味着它现在正式成为标准。 1 ECMAScript 2022编辑 本次发布的编辑有: Shu-yu Guo[2] Michael Ficarra[3] Kevin Gibbons[4] 2 ECMAScript 2022有什么新内…

联想(Lenovo)小新310经典版进bios方法

1,找到novo按钮。 2,在关机的状态下桶一下小孔,不用任何操作,电脑进入bios选择界面。转载于:https://www.cnblogs.com/senior-engineer/p/6761457.html

C#中的匿名类型

这节来讲一下C#中的匿名类型。匿名类在C#中,我们可以不去显示的声明一个类,而是通过匿名类去临时声明一个类结构去帮助我们去完成一些功能。声明一个匿名类,我们可以像下面这样做:var Anonymousnew {name"charles",year…

MySQL之MHA高可用集群

目录 一、MHA概述 1.1.MHA 是什么 1.2.MHA 的组成 1.3.MHA 的特点 二、MHA搭建准备 2.1.实验思路 三、MHA搭建 3.1配置主从复制 3.2.安装 MHA 软件 3.3.故障模拟 3.4.故障修复 四、总结 一、MHA概述 1.1.MHA 是什么 1.MHA(MasterHigh Availability&…

Tensorflow之安装

1.fellow the instruction of https://www.tensorflow.org/install/install_linux#installing_with_anaconda 2.anaconda安装,修改~/.bash_profile为 export PATH~/anaconda2/bin:/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRAR…

2、Saltstack的数据系统

一、Grainsgrains是salt用来收集minion端底层系统信息的接口。比如,操作系统type、域名 、IP地址、内存及其他相关系统属性信息等。存储在minion端,用于保存minion端数据信息。minion启动时才加载grains信息,所以他时静态的,Grain…

配置中心 App Configuration (一):轻松集成到Asp.Net Core

写在前面在日常开发中,我这边比较熟悉的配置中心有,携程Apollo,阿里Nacos(配置中心,服务治理一体)之前文章:Asp.Net Core与携程阿波罗(Apollo)的第一次亲密接触总体来说,Apollo和Nacos社区都比较活跃&#…

stop-hbase.sh一直处于等待状态

今天关闭HBase时,输入stop-hbase.sh一直处于等待状态 解决方法: 先输入:hbase-daemon.sh stop master 再输入:stop-hbase.sh就可以关闭HBase集群了。 转载于:https://www.cnblogs.com/lijinze-tsinghua/p/8667761.html

shell编程100例

1、编写hello world脚本 #!/bin/bash# 编写hello world脚本echo "Hello World!"2、通过位置变量创建 Linux 系统账户及密码 #!/bin/bash# 通过位置变量创建 Linux 系统账户及密码#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数 useradd "$1" …

sqlserver 分页

select top 10 numComImg.* from( select row_number() over(order by id asc) as rownumber,* from (select * FROM [TCCLine].[dbo].[CLine_CommonImage]) as comImg)as numComImg where rownumber>40select top 10 * --10 为页大小from [TCCLine].[dbo].[CLine_CommonIma…

详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] good

目录 前言现象源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口的具体应用常用HandlerMethodArgumentResolver介绍常用HandlerMethodReturnValueHandler介绍本文开头现象…

instancing render

当要绘制同一个东西很多次的时候,最简单的想法可能是循环调用glDrawArrays(),但这样会造成性能的损失。因为当显卡在渲染一个物体的时候,可能并不需要太多时间,但系统会花大量的时间,频繁的调用draw命令,再…

对不起,我不是一个自律的人

大家好,我是 🐟💨。前天,星球 的一位大学生朋友问了我几个问题:你大学时如何安排每日的时间?为什么能学那么多技术?你会学习到很晚吗?你是如何保持自律的?我觉得这几个问…

保证接口数据安全的10种方案

前言 大家好,我是程序汪,互联网项目需要特别注意数据安全,如果你简历上是互联网类型项目,安全方面肯定要能说出个一二三,下面分享下这方面的干货,大家可以记住几条,面试时好说道说道 我们日常…