Java设计模式学习记录-简单工厂模式、工厂方法模式
前言
之前介绍了设计模式的原则和分类等概述。今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍。
简单工厂模式
做法:创建一个工厂(方法或类)用来制造对象。
当一个人想要用手机的时候,需要自己创建手机然后来使用。
如下:
public class IphoneX {
public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 {
public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
}
}
public class Customer {
/**
* 使用手机
*/
@Test
public void usePhone(){
IphoneX iphoneX = new IphoneX();
Iphone8 iphone8 = new Iphone8();
}
}
这种实现方式,客户在使用的手机的时候会看到手机的具体实现方式,客户就和手机的耦合度非常高,其实客户并不关心手机具体是什么实现的,为了降低耦合,就出现了工厂类,把手机的制造过程放到工厂里去实现。客户想使用手机时,将手机型号传递给工厂类里创建手机的方法就可以了。而不必关心手机制造的整个过程,这样一来在创建手机的过程中添加额外的一些操作也显得很灵活。这种实现方式就是下面要介绍的简单工厂模式
public abstract class Iphone {
public Iphone(){
}
}
public class IphoneX extends Iphone{
public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 extends Iphone{
public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
}
}
工厂类:
public class FoxconnFactory {
/**
* 创建手机
* @param model 型号
* @return
*/
public static Iphone createIphone(String model){
switch (model){
case "X":{
return new IphoneX();
}
case "8":{
return new Iphone8();
}
default:break;
}
return null;
}
}
客户类:
public class Customer {
/**
* 使用手机
*/
@Test
public void usePhone(){
Iphone iphoneX = FoxconnFactory.createIphone("X");
Iphone iphone8 = FoxconnFactory.createIphone("8");
}
}
简单工厂模式的类图如下:

这个类图上包含三个角色:
- 工厂类角色(Factory):这是本模式的核心,含有一定的商业逻辑和判断逻辑。在Java中往往由一个具体类实现。
- 抽象产品角色(Abstract Iphone Class):一般是具体产品继承的父类或者实现的接口,在Java中由一个具体类来实现。
- 具体产品角色(IphoneX):工厂类所创建的对象就是此角色的实例,在Java中由一个具体类来实现。
在实际情况中如果我们想使用新的型号的手机,就需要改造FoxconnFactory这个类(在类中加case)这违背了开闭原则,因为在使用新产品的时候,工厂类是属于被动改变的。为了解决这种情况,就出现了工厂方法模式,工厂方法模式与简单工厂模式的最大不同在于,简单工厂模式只有一个(对于一个项目或一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。
工厂方法模式提供了多个实现相同接口的工厂类,这样每个工厂类生产不同类型的产品,这样如果新增加一款手机只需要新增加一个生产此款手机的工厂类就可以了,不用去改变已经存在的工厂类。这样就符合开闭原则了。
例子如下:
public abstract class Iphone {
public Iphone(){
}
}
public class IphoneX extends Iphone{
public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 extends Iphone{
public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
}
}
工厂类:
public interface Factory {
Iphone createIphone();
}
public class FoxconnFactory implements Factory{
/**
* 创建iphoneX手机
* @return
*/
@Override
public Iphone createIphone(){
return new IphoneX();
}
}
public class HeShuoFactory implements Factory {
/**
* 生产iphone8手机
* @return
*/
@Override
public Iphone createIphone() {
return new Iphone8();
}
}
客户类:
public class Customer {
/**
* 使用手机
*/
@Test
public void usePhone(){
Factory foxconn = new FoxconnFactory();
Factory heshuo = new HeShuoFactory();
Iphone iphoneX = foxconn.createIphone();
Iphone iphone8 = heshuo.createIphone();
}
}
工厂方法模式结构图如下:

此结构图的中含四个角色:
- 抽象工厂角色(代加工工厂):这是工厂方法模式的核心,它与应用程序无关,是具体工厂角色必须实现的接口或者必须继承的父类。在Java中他由抽象类或者接口来实现。
- 具体工厂角色(富士康工厂):它含有与具体业务逻辑有关的代码。由应用程序调用,以创建对应的具体产品对象。在Java中它由具体类来实现。
- 抽象产品角色(苹果手机抽象类):它是具体产品继承父类或者是实现的接口。在Java中一般有抽象类或接口来实现。
- 具体产品角色(iphoneX手机):具体工厂角色所创建的对象就是此角色的实例。在Java中由具体的类来实现。
虽然说工厂方法模式解决了简单工厂模式的不满足开闭原则的问题,但是这也造成了,代码量的成本增加,当产品数量过多时,维护起来会很麻烦,反而简单工厂没有这么麻烦,当多个产品需要修改时,简单工厂模式仍然只需要修改唯一的工厂类。无论哪种方式都是以实现功能为目的。
对比一下得出个人结论:简单工厂模式,更简洁方便。工厂方法模式更松散,更先进。
Java设计模式学习记录-简单工厂模式、工厂方法模式的更多相关文章
- Java设计模式学习记录-享元模式
前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...
- Java设计模式学习记录-备忘录模式
前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Java设计模式学习记录-解释器模式
前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...
- Java设计模式学习记录-命令模式
前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...
- Java设计模式学习记录-外观模式
前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...
- Java设计模式学习记录-模板方法模式
前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- Java设计模式学习记录-桥接模式
前言 这次介绍结构型设计模式中的第二种模式,桥接模式. 使用桥接模式的目的就是为了解耦,松散的耦合更利于扩展,但是会增加相应的代码量和设计难度. 桥接模式 桥接模式是为了将抽象化与实现化解耦,让二者可 ...
随机推荐
- 马士兵hibernate(原始笔记)
马士兵hibernate(原始笔记) 课程内容 1 HelloWorld a) Xml b) annotation 2 Hibernate原理模拟 - 什么是O/R ...
- Linux vi 文本代码时显示行号或不显示行号
Linux vi 文本代码时显示行号或不显示行号 前提 安装了vim $vi ~/.vimrc 显示的话加上 set nu 不想显示的话可以注释掉 "set nu 之后 $source ~ ...
- Git和SourceTree配合使用
Git介绍 git是当今最强大的本地的分布式代码版本管理工具. git的核心概念与操作:开发环境,本地仓库,远程仓库.他们的关系如下图: 与CVS及SVN的比较: CVS及SVN都是集中式的版本控制系 ...
- C# 利用VS中的插件来打包并发布winfrom程序
1.先在VS 的扩展更新中搜索此插件[2015 installer Projects],点击下载,安装需要关闭VS 2.安装完毕之后新建项目 3.选择“application folder”项,然后在 ...
- ovs-appctl 命令合集
通用命令 exit 优雅关闭ovs-vswitchd进程 qos/show interface 查询内核中关于qos的配置以及和给出端口有关的状态 cfm/show [interface]显示在指定端 ...
- js判断是否手机自动跳转移动端
写法一: {literal} <script> //判断是否手机自动跳转 var browser={versions:function(){var u=navigator.userAgen ...
- Spring学习笔记1——IOC: 尽量使用注解以及java代码
在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目. 预想的基本流程如下: 1.用户网站注册,填写用户名.密码.email.手机号信息,后台存入数据库后返回ok.(学习IO ...
- Yii2 Apache + Nginx 路由重写
一.什么是路由重写 原本的HTTP访问地址: www.test.com/index.php?r=post/view&id=100 表示这个请求将由PostController 的 action ...
- vue教程3-03 vue组件,定义全局、局部组件,配合模板,动态组件
vue教程3-03 vue组件,定义全局.局部组件,配合模板,动态组件 一.定义一个组件 定义一个组件: 1. 全局组件 var Aaa=Vue.extend({ template:'<h3&g ...
- odoo 开发基础 -- 视图之widget
Odoo 中的widget many2many_tags one2many_list selection progressbar selection statusbar handle monetary ...