Java中的工厂模式

设计模式遵循原则

  • 开闭原则:对扩展开放,对修改关闭
  • 里氏代换原则:只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被覆用。而衍生类也能够在基类的基础上增加新的行为
  • 依赖倒转原则:开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体
  • 接口隔离原则:使用多个隔离的接口来降低耦合度
  • 迪米特法原则:最少知道原则。一个实体应该尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立
  • 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。继承实际上破环了类的封装性,超类的方法可能会被子类修改。

工厂模式

简单工厂模式

简单工厂模式当中,一个工厂负责生产所有的产品。如上图所示,无论是戴尔鼠标还是惠普鼠标,都在一家鼠标工厂中生产。工厂通过用户的需要生产不同的鼠标,即用户传入生产鼠标的参数,工厂返回生产出的鼠标实体。

具体实现如下:

//鼠标基类
class Mouse{public void sayHi(){};
}
//鼠标扩展类
class DellMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("产品:戴尔鼠标");}
}
class HpMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("产品:惠普鼠标");}
}
//鼠标工厂
class MouseFactory{//生产鼠标的方法,所有的鼠标都通过该方法生成public static Mouse createMouse(int i) {switch (i) {case 0: return new DellMouse();case 1: return new HpMouse();default: return null;}}
}
public class NormFactory {public static void main(String[] args) {Mouse hpm = MouseFactory.createMouse(1);Mouse dellm = MouseFactory.createMouse(0);hpm.sayHi();dellm.sayHi();}
}

打印结果如下:

产品:惠普鼠标
产品:戴尔鼠标

上述模式下,所有的鼠标都在同一个MouseFactory工厂下生产,有一个统一的create静态方法。在使用工厂时,不需要对工厂进行实例化,只需要调用该静态方法便可得到相应的产品。

但如果用户需要添加新一类的产品,例如有一项华硕鼠标,工厂要生产该产品则需要改create函数,这有悖于设计原则的开闭原则。

工厂模式

在该模式下,不同品牌的产品交由不同的工厂来生产,有一个统一的工厂接口,生产该产品的工厂都要实现该接口。

生产哪种产品不再由参数决定,而是在创建工厂时让工厂来决定,例如惠普的工厂只会生产惠普的鼠标,而戴尔的工厂只会生产戴尔的鼠标。

具体实现如下:

class Mouse{public void sayHi(){};
}class DellMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("产品:戴尔鼠标");}
}
class HpMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("产品:惠普鼠标");}
}
//生产工厂接口
interface MouseFactory{public Mouse createMouse();
}
//不同的鼠标交由不同的工厂生产
class HpMouseFactory implements MouseFactory{@Overridepublic Mouse createMouse() {return new HpMouse();}
}
class DellMouseFactory implements MouseFactory{@Overridepublic Mouse createMouse() {return new DellMouse();}
}
public class NormFactory {public static void main(String[] args) {MouseFactory hpFact = new HpMouseFactory();MouseFactory dellFact = new DellMouseFactory();Mouse hpm = hpFact.createMouse();Mouse dellm = dellFact.createMouse();hpm.sayHi();dellm.sayHi();}
}

打印结果如下:

产品:惠普鼠标
产品:戴尔鼠标

该模式下代码的可扩展性大大提高,当需要添加一种商品时,只需要添加生产该商品的工厂,并让其实现生产工厂接口即可。

但在该模式下,商品的生产变得更为复杂,我们要得到一件商品,必须先得到一座生产该商品的工厂,再调用该工厂的生产方法才能得到该商品。

抽象工厂模式

该模式下的工厂生产的产品不唯一,同一品牌的工厂有着各种不同的产品,相当于是工厂模式的一个加强版。

具体实现如下:

class Mouse{public void sayHi(){};
}class DellMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("产品:戴尔鼠标");}
}
class HpMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("产品:惠普鼠标");}
}class KeyBoard {public void kick(){};
}
class HpKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("产品:惠普键盘");}
}
class DellKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("产品:戴尔键盘");}
}
//总的工厂接口
interface PcFactory {public Mouse createMouse() ;public KeyBoard createKeyBoard() ;
}
class HpFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}@Overridepublic KeyBoard createKeyBoard() {return new HpKeyBoard();}
}
class DellFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}@Overridepublic KeyBoard createKeyBoard() {return new DellKeyBoard();}
}//当需要增加一个华硕工厂时:
class AsusMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("产品:华硕鼠标");}
}
class AsusKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("产品:华硕键盘");}
}
class AsusFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new AsusMouse();}@Overridepublic KeyBoard createKeyBoard() {return new AsusKeyBoard();}
}public class NormFactory {public static void main(String[] args) {PcFactory hpFact = new HpFactory();Mouse hpm = hpFact.createMouse();KeyBoard hpkbd = hpFact.createKeyBoard();PcFactory dellFact = new DellFactory();Mouse dellm = dellFact.createMouse();KeyBoard dellkbd = dellFact.createKeyBoard();hpm.sayHi();dellm.sayHi();hpkbd.kick();dellkbd.kick();}
}

打印结果如下:

产品:惠普鼠标
产品:戴尔鼠标
产品:惠普键盘
产品:戴尔键盘

但该模式如果要添加产品时,需要修改PcFactory、DellFactory、HpFactory等所有实现了PcFactroy接口的工厂类,这是十分不好的。

转载于:https://www.cnblogs.com/JuanF/p/9275833.html

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

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

相关文章

世界时钟 软件_Clocker for Mac(世界时钟软件)

Clocker for Mac是一款Mac平台上免费的世界时钟工具,方便我们查看世界各地的时间,它是开源免费的,完全没有广告。包括数百个时区,支持24小时制或AM / PM,macz提供Clocker mac免费版,欢迎前来下载&#xff0…

Mac 设置 NDK

2019独角兽企业重金招聘Python工程师标准>>> 1、首先查看我自己的android studio ,找到以下路径 如上图,打开一个 AS 项目,file - project structure 这是我的3 个路径 Ndk /Users/dhbm/Library/Android/sdk/ndk-bundle Sdk /User…

Workbench has not been created yet

原因是:加载的插件变更后需要清理 在启动参数最后加入 -clean

四参数拟合曲线_每周放送|曲线拟合

曲线拟合No.1什么是曲线拟合所谓的曲线拟合,就是使用某一个模型(或者称为方程式),将一系列的数据拟成平滑的曲线,以便观察两组数据之间的内在联系,了解数据之间的变化趋势。No.2曲线拟合的应用在数据分析时,我们有时需…

Spark集群运行jar包程序里的print日志哪里去了?

默认情况下,是输出到stdout里的。 方法一: 进入work所在机器的spark安装目录下的work目录,里面有日志输出。 方法二: 进入spark web ui 里 点击stdout就可以查看,如果没有可能在其他work上。

qt 批量裁剪图片_照片变素描,不用下载App,好用的在线图片处理及图库

我们要处理图片时,无论是在电脑还是手机上,往往都需要下载软件,但如果你只是临时用一下的话,下载软件难免显得工程有点浩大。下面就推荐几个图片处理网站,打开网页就能用。1、图片处理 funny。pho。to这个网站提供了很…

Intellij IDEA15:建立Scala的Maven项目

原文链接:http://blog.csdn.net/silentwolfyh/article/details/51172369 ------------------------------------------------------------------------------------ 在创建Scala的Maven之前要安装JavaJDK 、 Scala 的JDK 、 Maven配置,请参考下面 Int…

linux临时启动进程命令,Linux常用命令(一)服务控制及优化启动过程

Linux常用命令(一)服务控制及优化启动过程一、Red hat系统开机引导过程1、linux操作系统的引导过程一般包括以下几个阶段:开机自检、MBR引导、GRUB菜单、加载Linux内核、init进程初始化。2、Linux系统中的进程使用数字进行标记,每个进程的身份标记号称为…

linux 解决端口占用

2019独角兽企业重金招聘Python工程师标准>>> 1. netstat -apn|grep 9876 2.kill -9 端口号 --------- java 在linux后台运行的命令 ------------- nohup java -jar demo-shiro-0.0.1-SNAPSHOT.jar >temp.txt & 转载于:https://my.oschina.net/likaixuan0/…

IDEA中 @override报错的解决方法

原文路径:http://www.cnblogs.com/printN/p/6870036.html ------------------------------------ 今天用IDEA导入一个java工程时,碰上一个问题,代码中所有override处标红,并提示:override不支持对接口的实现。 网上百…

Linux目录的可写意味着,Linux权限分析 - osc_h5427nyq的个人空间 - OSCHINA - 中文开源技术交流社区...

在学习Linux的权限之前,我们先来理解几个概念:可读,可写 、可执行Linux的文件和目录有以下三种方式:r 、w 、x:可读,可写 、可执行r-可读(read)w-可写(write)x-可执行(execute)所有者 、所属组 、其他人Linux的文件和目录又可以有…

【深度学习篇】--Windows 64下tensorflow-gpu安装到应用

一、前述 一直以为自己的笔记本不支持tensflow-gpu的运行,结果每次运行模型都要好久。偶然间一个想法,想试试自己的笔记本,结果竟然神奇的发现能用GPU。于是分享一下安装步骤. 二、具体 因为版本之间有严格的对应关系,所以本文就将…

idea中Error:java: Compilation failed: internal java compiler error

Error:java: Compilation failed: internal java compiler error 原因是没有设置好 java compiler,检查下 File-----setting---compiler----java compoler

linux版本fedora,技术|初级:如何更新 Fedora Linux 系统

本快速教程介绍了更新 Fedora Linux 安装的多种方法。安装 Fedora 之后,我做的第一件事就是尝试安装一些软件。我打开软件中心,发现该软件中心已“损坏”。 我无法从中安装任何应用程序。我不确定我的系统出了什么问题。在团队内部讨论时,Abh…

linux 开源邮件 系统,4 个开源的命令行邮件客户端

无论你承认与否,email并没有消亡。对那些对命令行至死不渝的 Linux 高级用户而言,离开 shell 转而使用传统的桌面或网页版邮件客户端并不适应。归根结底,命令行最善于处理文件,特别是文本文件,能使效率倍增。幸运的是&…

kafka清理数据日志

背景问题: 使用kafka的路上踩过不少坑,其中一个就是在测试环境使用kafka一阵子以后,发现其日志目录变的很大,占了磁盘很大空间,定位到指定目录下发现其中一个系统自动创建的 topic,__consumer_offsets-45&a…

修改docker-仓库资源地址Error response from daemon: Get https://index.docker.io/v1/search

[rootzengmg /]# docker search centosError response from daemon: Get https://index.docker.io/v1/search?qcentos: read tcp 52.200.132.201:443: i/o timeout docker在中国已经有了仓库:https://www.docker-cn.com/registry-mirror 根据上面网站提供的修改方法…

Apache发布Groovy 2.5正式版及3.0预览版

Apache基金会最近发布了Groovy2.5,新功能包括:\\AST转换的改进\新的宏支持\其他杂项改进\运行Groovy 2.5至少需要JDK 7,在JDK 9上运行可以忽略良性警告。\\尽管最近人们把关注点转到了其他JVM语言上(如Kotlin)&#xf…

自动飞行控制系统_波音公司将重设计737MAX自动飞行控制系统!力求十月前复飞...

据西雅图时报8月1日报道,美国联邦航空管理局(FAA)在6月份对波音737 MAX飞行控制系统进行新的严格测试时,发现了一个潜在的缺陷,该缺陷促使波音公司对其基本的软件设计进行变革。波音公司如今正在改变737 MAX的自动飞行控制系统软件&#xff0…

每日一题——LeetCode141.环形链表

个人主页:白日依山璟 专栏:Java|数据结构与算法|每日一题 文章目录 1. 题目描述示例1:示例2:示例3:提示: 2. 思路3. 代码 1. 题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某…