Java 设计模式系列(4) —— 工厂模式
工厂方法模式
工厂模式用于实现逻辑的封装,并通过公共的忌口提供对象的实例化服务,在添加新类时只需要做少量的修改。
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();
}
具体产品
- FruitCandy
public class FruitCandy implements Candy {@Overridepublic void testCandy() {System.out.println("Test FruitCandy");}}
- 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();
}
具体产品
- redCandy
public class RedCandy implements Candy {@Overridepublic void enjoyCandy() {System.out.println("Enjoy RedCandy");}
}
- 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();
}
具体产品角色
- 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");}}
- 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");}
}
- 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;}
}
具体工厂
- HardCandyFactory
public class HardCandyFactory extends CandyFactory {@Overridepublic Candy productCandy() {return new HardCandy();}}
- 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");}}
- 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();}
具体工厂
- AppleFlavorCandyFactory
public class AppleFlavorCandyFactory implements CandyFactory {@Overridepublic HardCandy createHardCandy() {return new AppleHardCandy();}@Overridepublic SoftCandy createSoftCandy() {return new AppleSoftCandy();}}
- OrangeFlavorCandyFactory
public class OrangeFlavorCandyFactory implements CandyFactory {@Overridepublic HardCandy createHardCandy() {return new OrangeHardCandy();}@Overridepublic SoftCandy createSoftCandy() {return new OrangeSoftCandy();}}
抽象产品
- SoftCandy
public interface SoftCandy {public void tasteSoftCandy();
}
- 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");}}
- AppleSoftCandy
public class AppleSoftCandy implements SoftCandy {@Overridepublic void tasteSoftCandy() {System.out.println("The Apple Soft Candy taste delicious");}}
- OrangeHardCandy
public class OrangeHardCandy implements HardCandy {@Overridepublic void tasteHardCandy() {System.out.println("The Orange Hard Candy taste delicious"); }}
- OrangeSoftCandy
public class OrangeSoftCandy implements SoftCandy {@Overridepublic void tasteSoftCandy() {System.out.println("The Orange Soft Candy taste delicious");}}
抽象工厂模式的优缺点
优点:
- 当需要产品族时,抽象共产可以保证客户端始终只使用一个产品的产品族
- 抽象工厂增强了程序的可扩展性,对于新产品族的增加,秩序实现一个新的具体工厂即可
缺点:
- 规定了所有可能被创建的产品的集合,产品族中添加新的扩展会更加困难
- 增加了系统的抽象性和理解难度
Java 设计模式系列(4) —— 工厂模式相关推荐
- 设计模式系列·抽象工厂模式
前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...
- java设计模式3种工厂模式
java设计模式3种工厂模式 2010-01-08 16:06:36| 分类: JAVA技术|举报|字号 订阅 下载LOFTER客户端 工厂模式分为三种: Simple Factory模式 专门定义 ...
- Java设计模式系列--责任链模式(应用)
原文网址:Java设计模式系列--责任链模式(应用)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Java设计模式中的责任链模式的一些使用场景. 责任链模式的好处 符合单一职责原则 每个功能 ...
- Java设计模式之简单工厂模式实验(软件工程综合实践课程第二周)
实验目的 1 .理解软件设计的相关理论 : 2 .理解面向对象设计原则: 实验内容 1 .简单工厂模式实验: (1) 参考讲义上的代码,利用简单工厂模式完成计算器应用程序: (2) 画出计算器程序简单 ...
- Java设计模式之 简单工厂模式和工厂方法实验报告书
目录 Java设计模式之 1 简单工厂模式和工厂方法实验报告书 1 实验四:简单工厂模式和工厂方法 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1简单工厂模式:女娲 2 3.2简单工 ...
- java设计模式---三种工厂模式
工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory). GOF ...
- 抽象工厂模式_设计模式系列—抽象工厂模式
前言 23种设计模式速记 单例(singleton)模式 工厂方法(factory method)模式 23种设计模式快速记忆的请看上面第一篇,前面说完了工厂方法模式,我们发现工厂方法模式存在一个严重 ...
- JAVA设计模式之抽象工厂模式
本文继续介绍23种设计模式系列之抽象工厂模式. 前面已经介绍过简单工厂模式和工厂方法模式,这里继续介绍第三种工厂模式-抽象工厂模式,还是以汽车的制造为例. 例子背景: 随着客户的要求越来越高,宝马车需 ...
- Java设计模式之 抽象工厂模式实验报告书
目录 Java设计模式之 1 抽象工厂模式实验报告书 1 实验四:抽象工厂模式 2 一.实验目的 2 二.实验内容 2 三.实验步骤 2 3.1抽象工厂模式:电器工厂 2 3.2 car 6 3.3 ...
最新文章
- NLP实战:利用Python理解、分析和生成文本 | 赠书
- Action Golf 四个魔法球实战训练系列_huatuo_新浪博客
- Ext Tree异步树的增加修改删除的简单实现~
- 拉格朗日乘子法 学习笔记
- Oracle数据库的性能调整
- 「Github」Linux/Ubuntu下终端Github教程与手册
- ssh excel 导入 mysql_ssh poi解析excel并将数据存入数据库
- CheckBoxList 全选(jquery版本)
- linux yum 安装widget,CentOS 7安装Qt5.12.1过程
- arcgis加载dwg显示一个点_shp文件转为dwg之后在arcgis下打开属性表有高程信息但在cad里面打开为何没高程 - 地学 - 小木虫 - 学术 科研 互动社区...
- 第 15 章 代理模式
- 【动态规划】LeetCode 377. Combination Sum IV
- Java Windows,Linux视频抽帧的4种方式
- 《莫烦Python3基础教程》学习笔记
- IT资源专业搜索-www.easysoo.cn
- Python做出来的数据可视化真香!!
- 【HDU4622】Reincarnation(后缀自动机)
- asp.net 下载文件几种方式
- java 音频 傅立叶_关于FFT分析音频的小归纳
- 机器学习常见求逆矩阵的方法
热门文章
- 汽车RKE方案设计原理及实现
- ACM:P: 三家人
- 新手指南:主板BIOS刷新方法全收集
- 计算机应用基础要上机,计算机应用基础考试需要上机吗?
- 第079封“情书”:“I服了You”Cloth Solver From Scratch<Entagma>Houdini 2018
- AtCoder Beginner Contest 187 F - Close Group
- 电视盒子的世界,你看不懂就对了
- 【完全不同的解决方案】no Qt platform
- Excel自动得出结果(数字前后可以添加文字备注)功能实现操作步骤
- realloc函_realloc函数使用规则