工厂方法模式

工厂模式用于实现逻辑的封装,并通过公共的忌口提供对象的实例化服务,在添加新类时只需要做少量的修改。

1. 静态工厂模式(简单工厂模式)

静态工厂属于创建者模式,静态工厂模式的实现需要三个角色

  • 简单工厂:负责创建具体产品产品,工厂类的方法可以被外界直接调用
  • 抽象产品:在 Java 中,抽象产品是由抽象类或者接口担任的,用以让具体产品继承或实现
  • 具体产品:在 Java 中,具体产品是工厂类创建的主要对象。
静态工厂的通用写法

工厂角色

public class CandyFactory {public enum CandyKind{FRUITCANDY("fruitCandy"),COLACANDY("COLACANDY");private String kind;CandyKind(String kind){this.kind = kind;}public String getCandyKind() {return this.kind;}}public Candy createCandy(String kind) {if(kind.equals(CandyKind.COLACANDY.getCandyKind()))return new ColaCandy();if(kind.equals(CandyKind.FRUITCANDY.getCandyKind())) {return new FruitCandy();}return null;}}

抽象产品

public interface Candy {public void testCandy();
}

具体产品

  1. FruitCandy
public class FruitCandy implements Candy {@Overridepublic void testCandy() {System.out.println("Test FruitCandy");}}
  1. ColaCandy
package com.stu.edu.part2.Factorypattern.demo2;public class ColaCandy implements Candy {@Overridepublic void testCandy() {System.out.println("Test ColaCandy");}}

上述写法符合了迪米特法则,但是该种写法难以符合开闭原则,一旦有新的产品品种加入,就需要修改工厂类,因此该种写法使用与具体产品类不多,且具体产品种类长时间不改变的情况。

静态工厂与反射的结合

该方案采用一个 HashMap 存储创建的具体产品与 String 之间的映射,使用反射的方式来创建类。这样不仅代码代码更加精简,并且也符合了开闭原则

工厂角色

public class CandyFactory {private static Map<String,Class> candyMap = new HashMap<>();public void registerCandy(String kind,Class candyclass) {candyMap.put(kind, candyclass);}public Candy createCandy(String kind) {Candy candy = null;if(candyMap.containsKey(kind)) {try {candy = (Candy)candyMap.get(kind).newInstance();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {return candy;}           }return candy;}}

抽象产品

public interface Candy {public void enjoyCandy();
}

具体产品

  1. redCandy
public class RedCandy implements Candy {@Overridepublic void enjoyCandy() {System.out.println("Enjoy RedCandy");}
}
  1. WhiteCandy
public class WhiteCandy implements Candy {@Overridepublic void enjoyCandy() {System.out.println("Enjoy WdhiteCandy");}}
静态工厂的进一步优化

当然,并非任何时候都适用反射的方式来创建对象,因此我们可以调用类自身的创建方式来实现。我们可以为每一个类创建一个 newInstance 方法,用于返回该类自身的对象。

工厂角色

public class CandyFactory {private static Map<String,Candy> candyMap = new HashMap<String,Candy>();public void RegisterCandy(String kind,Candy candy) {candyMap.put(kind, candy);}public  Candy createCandy(String kind) {if(candyMap.containsKey(kind)) {candyMap.get(kind).newInstance();}return null;}}

抽象产品角色

public interface Candy {public Candy newInstance();public void showCandy();
}

具体产品角色

  1. SoftCandy
public class SoftCandy implements Candy {@Overridepublic SoftCandy newInstance() {// TODO Auto-generated method stubreturn new SoftCandy();}@Overridepublic void showCandy() {System.out.println("This is a SoftCandy");}}
  1. HardCandy
public class HardCandy implements Candy {@Overridepublic HardCandy newInstance() {return new HardCandy();}@Overridepublic void showCandy() {// TODO Auto-generated method stubSystem.out.println("This is a HardCandy");}
}
  1. MilkCandy
public class MilkCandy implements Candy {@Overridepublic MilkCandy newInstance() {// TODO Auto-generated method stubreturn new MilkCandy();}@Overridepublic void showCandy() {// TODO Auto-generated method stubSystem.out.println("This is a MilkCandy");;}
}
简单工厂模式的优缺点

优点:

  • 结构简单,调用方便
  • 共产和产品职责区分明确

缺点:

  • 工厂类单一,负责所有产品的创建,产品基数增多时工厂类会非常臃肿

2. 工厂方法模式

工厂方法模式又称为多态性工厂模式,指定一个创建对象的接口,但由实现这个接口的类来决定实例化哪一个类。

在工厂方法模式中,共涉及到4个角色:

  • 抽象工厂角色:定义产品对象的产生
  • 具体工厂角色:实现了抽象共产,负责具体产品的创建
  • 抽象产品角色:定义具体产品的共性
  • 具体产品角色:具体产品的实例
工厂方法模式示例

抽象工厂

public abstract class CandyFactory {public abstract Candy productCandy();public List<Candy> orderProduct(int number) {List<Candy> candyList = new ArrayList<>();int i=0;do {Candy candy = productCandy();candyList.add(candy);i++;}while(i<number);return candyList;}
}

具体工厂

  1. HardCandyFactory
public class HardCandyFactory extends CandyFactory {@Overridepublic Candy productCandy() {return new HardCandy();}}
  1. SoftCandyFactory
public class SoftCandyFactory extends CandyFactory {@Overridepublic Candy productCandy() {return new OrangeSoftCandy();}}

抽象产品

public interface Candy {public void enjoyCandy();}

具体产品

1.SoftCandy

public class OrangeSoftCandy implements Candy {@Overridepublic void enjoyCandy() {System.out.println("Enjoy Orange SoftCandy");}}
  1. OrangeHardCandy
public class HardCandy implements Candy {@Overridepublic void enjoyCandy() {System.out.println("Enjoy Orange HardCandy");}}
工厂方法模式的优缺点

优点:

  • 良好的封装性
  • 优秀的可扩展性,灵活性,对于新产品或者产品类的创建,只需多写一个相应的工厂类,而无需修改工厂类,调用时也不会
  • 屏蔽产品类,产品类如何实现变化无需调用者都不用关心,只需关注接口即可

缺点:

  • 类产品过多,会增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品

3. 抽象工厂模式

抽象工厂指提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类。意思是,客户端不必指定产品的具体类型,创建多个产品族中的具体对象。

抽象工厂和工厂方法一样拥有四个对象:

  • 抽象工厂:声明创建抽象产品对象的一个操作接口
  • 具体工厂:实现创建具体产品对象的操作
  • 抽象产品:为一类产品对象声明一个接口
  • 具体产品:定义一个将被相应的具体工厂的创建的产品对象,是实现 AbstractProduct 接口

上图为 抽象工厂模式的一个 UML 图

我们可以借助下图帮助我们理解一下

抽象工厂模式示例

抽象工厂

public interface CandyFactory {public HardCandy createHardCandy();public SoftCandy createSoftCandy();}

具体工厂

  1. AppleFlavorCandyFactory
public class AppleFlavorCandyFactory implements CandyFactory {@Overridepublic HardCandy createHardCandy() {return new AppleHardCandy();}@Overridepublic SoftCandy createSoftCandy() {return new AppleSoftCandy();}}
  1. OrangeFlavorCandyFactory
public class OrangeFlavorCandyFactory implements CandyFactory {@Overridepublic HardCandy createHardCandy() {return new OrangeHardCandy();}@Overridepublic SoftCandy createSoftCandy() {return new OrangeSoftCandy();}}

抽象产品

  1. SoftCandy
public interface SoftCandy {public void tasteSoftCandy();
}
  1. HardCandy
public interface HardCandy {public void tasteHardCandy();
}

具体产品
1.AppleHardCandy

public class AppleHardCandy implements HardCandy {@Overridepublic void tasteHardCandy() {System.out.println("The Apple Hard Candy taste delicious");}}
  1. AppleSoftCandy
public class AppleSoftCandy implements SoftCandy {@Overridepublic void tasteSoftCandy() {System.out.println("The Apple Soft Candy taste delicious");}}
  1. OrangeHardCandy
public class OrangeHardCandy implements HardCandy {@Overridepublic void tasteHardCandy() {System.out.println("The Orange Hard Candy taste delicious");        }}
  1. OrangeSoftCandy
public class OrangeSoftCandy implements SoftCandy {@Overridepublic void tasteSoftCandy() {System.out.println("The Orange Soft Candy taste delicious");}}
抽象工厂模式的优缺点

优点:

  1. 当需要产品族时,抽象共产可以保证客户端始终只使用一个产品的产品族
  2. 抽象工厂增强了程序的可扩展性,对于新产品族的增加,秩序实现一个新的具体工厂即可

缺点:

  1. 规定了所有可能被创建的产品的集合,产品族中添加新的扩展会更加困难
  2. 增加了系统的抽象性和理解难度

Java 设计模式系列(4) —— 工厂模式相关推荐

  1. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

  2. java设计模式3种工厂模式

    java设计模式3种工厂模式 2010-01-08 16:06:36|  分类: JAVA技术|举报|字号 订阅 下载LOFTER客户端 工厂模式分为三种: Simple Factory模式 专门定义 ...

  3. Java设计模式系列--责任链模式(应用)

    原文网址:Java设计模式系列--责任链模式(应用)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Java设计模式中的责任链模式的一些使用场景. 责任链模式的好处 符合单一职责原则 每个功能 ...

  4. Java设计模式之简单工厂模式实验(软件工程综合实践课程第二周)

    实验目的 1 .理解软件设计的相关理论 : 2 .理解面向对象设计原则: 实验内容 1 .简单工厂模式实验: (1) 参考讲义上的代码,利用简单工厂模式完成计算器应用程序: (2) 画出计算器程序简单 ...

  5. Java设计模式之 简单工厂模式和工厂方法实验报告书

    目录 Java设计模式之 1 简单工厂模式和工厂方法实验报告书 1 实验四:简单工厂模式和工厂方法 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1简单工厂模式:女娲 2 3.2简单工 ...

  6. java设计模式---三种工厂模式

    工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory). GOF ...

  7. 抽象工厂模式_设计模式系列—抽象工厂模式

    前言 23种设计模式速记 单例(singleton)模式 工厂方法(factory method)模式 23种设计模式快速记忆的请看上面第一篇,前面说完了工厂方法模式,我们发现工厂方法模式存在一个严重 ...

  8. JAVA设计模式之抽象工厂模式

    本文继续介绍23种设计模式系列之抽象工厂模式. 前面已经介绍过简单工厂模式和工厂方法模式,这里继续介绍第三种工厂模式-抽象工厂模式,还是以汽车的制造为例. 例子背景: 随着客户的要求越来越高,宝马车需 ...

  9. Java设计模式之 抽象工厂模式实验报告书

    目录 Java设计模式之 1 抽象工厂模式实验报告书 1 实验四:抽象工厂模式 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1抽象工厂模式:电器工厂 2 3.2 car 6 3.3 ...

最新文章

  1. NLP实战:利用Python理解、分析和生成文本 | 赠书
  2. Action Golf 四个魔法球实战训练系列_huatuo_新浪博客
  3. Ext Tree异步树的增加修改删除的简单实现~
  4. 拉格朗日乘子法 学习笔记
  5. Oracle数据库的性能调整
  6. 「Github」Linux/Ubuntu下终端Github教程与手册
  7. ssh excel 导入 mysql_ssh poi解析excel并将数据存入数据库
  8. CheckBoxList 全选(jquery版本)
  9. linux yum 安装widget,CentOS 7安装Qt5.12.1过程
  10. arcgis加载dwg显示一个点_shp文件转为dwg之后在arcgis下打开属性表有高程信息但在cad里面打开为何没高程 - 地学 - 小木虫 - 学术 科研 互动社区...
  11. 第 15 章 代理模式
  12. 【动态规划】LeetCode 377. Combination Sum IV
  13. Java Windows,Linux视频抽帧的4种方式
  14. 《莫烦Python3基础教程》学习笔记
  15. IT资源专业搜索-www.easysoo.cn
  16. Python做出来的数据可视化真香!!
  17. 【HDU4622】Reincarnation(后缀自动机)
  18. asp.net 下载文件几种方式
  19. java 音频 傅立叶_关于FFT分析音频的小归纳
  20. 机器学习常见求逆矩阵的方法

热门文章

  1. 汽车RKE方案设计原理及实现
  2. ACM:P: 三家人
  3. 新手指南:主板BIOS刷新方法全收集
  4. 计算机应用基础要上机,计算机应用基础考试需要上机吗?
  5. 第079封“情书”:“I服了You”Cloth Solver From Scratch<Entagma>Houdini 2018
  6. AtCoder Beginner Contest 187 F - Close Group
  7. 电视盒子的世界,你看不懂就对了
  8. 【完全不同的解决方案】no Qt platform
  9. Excel自动得出结果(数字前后可以添加文字备注)功能实现操作步骤
  10. realloc函_realloc函数使用规则