目录

  • 实例
    • 图片读取器
    • 简单工厂解决方案
  • 工厂方法模式
    • 概念
    • 工厂方法解决方案
    • 方案的演进(配置文件)
  • 总结
  • 源码

实例

先看一个例子

图片读取器

设计一个可以读取不同类型图片格式的程序,针对每种图片格式都需要一个图片读取器,如GIF读取器用于读取GIF图片,JPG读取器用于读取JPG图片,需充分考虑系统的灵活性和可扩展性

简单工厂解决方案

  • 使用简单工厂的解决方案大致如下:
  • Img.java
/*** @Description 图片*/
public abstract class Img {/*** 获取图片源*/public abstract void getSource();
}
  • GifImg.java
/*** @Description GIF图片*/
public class GifImg extends Img {@Overridepublic void getSource() {System.out.println("获取GIF图片源");}
}
  • JpgImg.java
/*** @Description JPG图片*/
public class JpgImg extends Img {@Overridepublic void getSource() {System.out.println("获取JPG图片源");}
}
  • ImgFactory.java
/*** @Description 图片简单工厂类*/
public class ImgFactory {/*** 简单工厂获取图片产品类* @param args* @return*/public static Img getImg(String args) {Img img = null;if (args.equalsIgnoreCase("gif")) {img = new GifImg();} else if (args.equalsIgnoreCase("jpg")) {img = new JpgImg();}return img;}
}
  • Test.java
/*** @Description 图片简单工厂测试类*/
public class Test {public static void main(String[] args) {Img img = ImgFactory.getImg("gif");if (img == null) {return;}img.getSource();img = ImgFactory.getImg("jpg");if (img == null) {return;}img.getSource();}
}
  • 运行结果:
获取GIF图片源
获取JPG图片源
  • 通过上述代码,简单工厂方法模式只提供一个工厂类,通过所传入的参数的不同来创建不同的产品,该工厂类处于对产品类进行实例化的中心位置,其最大的缺点就是当有新产品要加入系统中时必须修改工厂类的源代码,违背开闭原则,如上述代码需要加入一个PNG的产品类势必要修改ImgFactory,如何实现增加新产品而不影响已有代码,接下来引出工厂方法模式,在工厂方法模式中,不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构

工厂方法模式

概念

  • 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类
  • 工厂方法模式又简称工厂模式(Factory Pattern

工厂方法解决方案

Img.java

/*** @Description 图片产品类*/
public abstract class Img {/*** 获取图片源*/public abstract void getSource();
}
  • ImgFactory.java
/*** @Description 图片工厂类(工厂方法模式)*/
public interface ImgFactory {/*** 获取图片产品类* @return*/Img getImg();
}
  • GifImg.java
/*** @Description GIF图片产品类*/
public class GifImg extends Img {@Overridepublic void getSource() {System.out.println("获取GIF图片源");}
}
  • GifImgFactory.java
/*** @Description Gif图片工厂类*/
public class GifImgFactory implements ImgFactory {@Overridepublic Img getImg() {return new GifImg();}
}
  • JpgImg.java
/*** @Description JPG图片产品类*/
public class JpgImg extends Img {@Overridepublic void getSource() {System.out.println("获取JPG图片源");}
}
  • JpgImgFactory.java
/*** @Description Gif图片工厂类*/
public class JpgImgFactory implements ImgFactory {@Overridepublic Img getImg() {return new JpgImg();}
}
  • Test.java
/*** @Description 工厂方法模式测试类*/
public class Test {public static void main(String[] args) {ImgFactory imgFetchFactory = new GifImgFactory();Img imgFetch = imgFetchFactory.getImg();imgFetch.getSource();imgFetchFactory = new JpgImgFactory();imgFetch = imgFetchFactory.getImg();imgFetch.getSource();}
}
  • 输出如下:
获取GIF图片源
获取JPG图片源
  • 类图如下:

  • 工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法(ImgFactory),而由其子类(JpgImgFactoryGifImgFactory)来具体实现工厂方法,创建具体的产品对象,与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色

方案的演进(配置文件)

  • 如上客户端Test.java调用代码还具有可改进的地方,可通过配置文件 + 反射实现在不修改客户端代码的基础上更换和增加新的图片读取方式

  • config.properties

factoryMethod.className=GifImgFactory
  • PropertiesUtil.java
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;/*** @Description Properties工具类*/
public class PropertiesUtil {/*** 根据key读取value* @Description: 相对路径, properties文件需在classpath目录下,*               比如:config.properties在包com.coisini.util,*               路径就是/com/coisini/util/config.properties* @param filePath* @param keyWord* @return String* @throws*/private static String getProperties(String filePath, String keyWord){Properties prop = new Properties();String value = null;try {InputStream inputStream = PropertiesUtil.class.getResourceAsStream(filePath);prop.load(inputStream);value = prop.getProperty(keyWord);} catch (IOException e) {e.printStackTrace();}return value;}/*** 根据配置文件提取类名返回实例对象* @param filePath* @param keyWord* @param packagePath* @return*/private static Object getBean(String filePath, String keyWord, String packagePath) {try {String className = getProperties(filePath, keyWord);Class<?> c = Class.forName(packagePath + className);return c.newInstance();} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取工厂方法实例对象* @return*/public static Object getFactoryMethodBean() {return getBean("/com/coisini/design/util/config.properties","factoryMethod.className","com.coisini.design.pattern.creational.factorymethod.v3.");}}
  • Test.java
/*** @Description 工厂方法模式测试类(配置文件反射实现方式)*/
public class Test {public static void main(String[] args) {ImgFactory imgFactory = (ImgFactory) PropertiesUtil.getFactoryMethodBean();Img img = imgFactory.getImg();img.getSource();}
}
  • 通过如上配置文件 + 反射实现方式,客户端代码无需使用new关键字来创建工厂对象,而是将具体工厂类的类名存在配置文件中,通过读取配置文件获取类名字符串,再使用反射机制根据类名字符串生成对象

总结

  • 优点
1、用户只需关心所需产品对应的工厂,无需关心创建细节
2、加入新产品符合开闭原则,提高可扩展性
  • 缺点
1、类的个数容易过多,增加复杂度
2、增加了系统的抽象性和理解难度
  • 适用场景
1、创建对象需要大量重复代码
2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
3、一个类通过子类来指定创建哪个对象

源码

  • GitHub:https://github.com/Maggieq8324/design_pattern.git

- End - - 个人学习笔记 - - 仅供参考 -

设计模式 - 工厂方法模式相关推荐

  1. 4. 星际争霸之php设计模式--工厂方法模式

    题记 ============================================================================== 本php设计模式专辑来源于博客(jy ...

  2. java 工厂方法_java设计模式-工厂方法模式

    1.工厂方法(FactoryMethod)模式的定义 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中.这满足创建型模式中所要求的"创建与使用相分离" ...

  3. 设计模式 | 工厂方法模式及典型应用

    工厂方法模式 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化.工厂方法模式让一个类的实例化延迟到其子类. 工厂方法模式又简称为工厂 ...

  4. python工厂模式 django_python设计模式-工厂方法模式

    题目:假设你有一个 pizza 店,功能包括下订单.做 pizza,你的代码会如何写呢? def order_pizza(): pizza = Pizza() pizza.prepare() pizz ...

  5. 工厂方法模式_1天1个设计模式——工厂方法模式

    意图 工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型. 问题 假设你正在开发一款物流管理应用.1.0版本只能支持处理卡车运输,因此大部分的代码都位 ...

  6. [设计模式] ------ 工厂方法模式

    工厂方法模式 手机厂造手机,肥皂厂造肥皂,药品厂造药品. 假设有一大类对象A1,A2,A3,A4-他们都有一个共同的父类A A1可以想成是手机,A2可以想成肥皂- (下面例子的A1Factory就是手 ...

  7. JAVA设计模式 - 工厂方法模式

    工厂方法模式(Factory Pattern) 是一种创建型设计模式 , 它是Java中最常用的设计模式之一 . 1 . 工厂方法模式的定义 定义一个创建对象的接口 , 让子类决定实例化哪一个类 . ...

  8. Java设计模式—工厂方法模式抽象工厂模式

    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...

  9. C#设计模式--工厂方法模式

    0.C#设计模式-简单工厂模式 设计模式: 工厂方法模式(Factory Method Pattern) 介绍:简单工厂模式是要在工厂类中通过数据来做个决策,在工厂类中的多个类中实例化出来其中一个要用 ...

  10. 设计模式 - 工厂方法模式 - 基于 Java 实现

    常见和工厂有关的设计模式 和工厂相关的设计模式主要有三种,工厂方法模式,抽象工厂模式: 在前面的博客中介绍了简单工厂模式,本篇博客主要介绍的是工厂方法模式 什么是工厂方法模式 工厂方法模式是简单工厂的 ...

最新文章

  1. 大型门户网站架构设计的可伸缩性
  2. Scrum联盟发布《2016年度Scrum状态调查报告》
  3. Java Servlet和JSP教程
  4. oracle新增表单,Oracle Retail(Retek)中Form生成列表方法总结
  5. NoHttp使用简析——Android网络请求框架(二)
  6. Linux服务器SSH免密登录
  7. Flutter进阶—创建有状态控件
  8. 谷歌了java集成开发_Spring整合Kaptcha谷歌验证码工具的开发步骤
  9. 基于物联网技术的电动车锂电池安全预警系统
  10. 30天自制操作系统——第二十四天增加命令行窗口
  11. 【游戏客户端】制作节奏大师Like音游(上)
  12. c++知识点汇总--数组
  13. hardfault常见原因_keil遇到hardfault时原因的查找
  14. HDUOJ 2059 龟兔赛跑——
  15. 鸿蒙OS平板界面,华为鸿蒙OS平板操作界面曝光,华为MatePad Pro2,搭载麒麟9000
  16. Bitvise——服务器与本地交互软件(适合大文件传输)
  17. php语言开始和结束分别为,PHP语言参考
  18. PAT乙级题目答案汇总 PAT (Basic Level) Practice (中文)
  19. 基于STM32分析内存分布图
  20. ACM顶会CIKM 2022放榜!度小满AI Lab三篇入选

热门文章

  1. 解决ValueError: Expected n_neighbors #60= n_samples,  but n_samples = 4, n_neighbors = 5
  2. 显示器的分辨率为1024*1024的显示模式,显示器中每个像素点的灰度等级为256级,则帧缓存容量至少为( ) bit
  3. 漫画 | 程序员为什么(爱吐槽)找不到妹子?
  4. 中国数学老师在 P 站上教微积分,年入 170 万?!…网友:看不懂,但我悟了!
  5. python内置函数lambda函数常见用法
  6. 机器学习(Machine Learning)amp;深度学习(Deep Learning)资料
  7. 超级简单的安卓课程设计——书籍信息查询
  8. Dockerfile精编细作(五)编辑可应用到正式环境的Dockerfile并构建java项目
  9. SLAM十四讲:第三讲习题
  10. 编写java888,用java编程,编写程序,求8+88+888+….+8888888888的和