前言

之前介绍了设计模式的原则和分类等概述。今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍。

简单工厂模式

做法:创建一个工厂(方法或类)用来制造对象。

当一个人想要用手机的时候,需要自己创建手机然后来使用。

如下:

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设计模式学习记录-简单工厂模式、工厂方法模式的更多相关文章

  1. Java设计模式学习记录-享元模式

    前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...

  2. Java设计模式学习记录-备忘录模式

    前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...

  3. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  4. Java设计模式学习记录-解释器模式

    前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...

  5. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  6. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

  7. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  8. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  9. Java设计模式学习记录-桥接模式

    前言 这次介绍结构型设计模式中的第二种模式,桥接模式. 使用桥接模式的目的就是为了解耦,松散的耦合更利于扩展,但是会增加相应的代码量和设计难度. 桥接模式 桥接模式是为了将抽象化与实现化解耦,让二者可 ...

随机推荐

  1. 前端开发 - HTML/CSS

    概述 HTML是英文HyperText Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记). 相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏览器 ...

  2. 用fastreport在进行多列打印时,默认是先行后列,如何改成先列后行排记录?

    例子程序中的6.fr3是在Page中设置 columns=2这样就是先行后列,7.fr3就是3列先列后行的例子 1     6 2     7 3     8 4     9 5     10 但如果 ...

  3. Android-ANR异常

    A N R : Application Not Responding : 应用没有响应异常 引发ANR的原因是,组件的主线程去执行了耗时操作多少秒,就会引发ARN异常: 引发ANR异常的案例: pac ...

  4. 转 iOS宏定义的使用与规范

    宏定义在很多方面都会使用,例如定义高度.判断iOS系统.工具类,还有诸如文件路径.服务端api接口文档.为了对宏能够快速定位和了解其功能,我们最好在定义的时候将其放入特定的头文件中,下面我抛砖引玉,对 ...

  5. INDEX--从数据存放的角度看索引

    测试表结构: CREATE TABLE TB1 ( ID ,), C1 INT, C2 INT ) 1. 聚集索引(Clustered index) 聚集索引可以理解为一个包含表中除索引键外多有剩余列 ...

  6. hadoop 的HDFS 的 standby namenode无法启动事故处理

    standby namenode无法启动 现象:线上使用的2.5.0-cdh5.3.2版本Hadoop,开启了了NameNode HA,HA采用QJM方式.hadoop的集群的namenode的sta ...

  7. 利用 LibWebP-NET 解码与编码 WebP 格式图片

    此文以后将会在我的新博客更新,有任何疑问可在我的新博文中提出 https://blog.clso.fun/posts/2019-03-02/vb-net-webp.html WebP 格式是谷歌开发并 ...

  8. net 把指定 URI 的资源下载到本地

    DirectoryInfo dir = new DirectoryInfo(AppContext.BaseDirectory); var path = dir.FullName + @"te ...

  9. Regular Expression

    It's a very elegant summary of regular expression from The AWK Programming Language. 1. The regular ...

  10. Java内存溢出问题总结

    使用Java那么久,在此总结一下Java中常见的内存溢出问题以及对应的解决思路 堆溢出 报错信息 java.lang.OutOfMemoryError: Java heap space 报错原因 堆中 ...