Java设计模式之工厂方法模式

负重前行的小牛 2020-11-08 21:03:40
java 设计 工厂 模式 厂方


工厂方法模式的定义:

工厂方法模式又叫做多态性工厂模式,指定义一个创建对象的接口,但由实现这个接口的类来决定实例化哪个类,工厂方法把类的实例化推迟到子类种进行。

在工厂方法模式中,不在由单一的工厂类生产产品,而是由工厂类的子类实现具体产品的创建。因此,当增加一个产品时,只需增加一个相应的工厂类的子类,实现

产品的创建,便可以解决简单工厂生产太多产品导致其内部代码臃肿(switch...case分支过多)的问题,也符合开闭原则。虽然在简单工厂模式中,我们用反射去解决

了这个问题,但是这种方式是有局限性的,因为我们不能保证每个需要创建的对象的构造方法,参数都是统一的。

工厂方法模式的应用场景:

  • 创建对象需要大量重复代码。
  • 客户端(应用层)不依赖产品类实例如何被创建、实现细节等。
  • 一个类通过其子类来指定创建哪个对象。

工厂方法模式的UML类图:

由上图可以看到,工厂方法模式主要包含4个角色。

  1. 抽象工厂(IFactory):是工厂方法模式的核心,与应用程序无关。任何在模式中创建对象的工厂类必须实现这个接口。
  2. 具体工厂(FactoryA,B,C):是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序直接调用以创建产品的对象。
  3. 抽象产品(IProduct):是工厂方法模式所创建的对象的超类型,也就是产品对象的公共父类或公共拥有的接口,以达到解耦的作用。
  4. 具体产品:(ProductA,B,C):这个角色实现了抽象产品角色所定义的接口。每个具体的产品和一个具体工厂一一对应。

 工厂方法模式案例:

package com.liuyi.designmode.creational.factory;
/**
* 电子书接口
*/
public interface EBook {
/**
* 阅读方法
*/
public void read();
}
package com.liuyi.designmode.creational.factory;
/**
* java语言书籍
*/
public class JavaBook implements EBook {
@Override
public void read() {
System.out.println("阅读java语言书籍");
}
}
package com.liuyi.designmode.creational.factory;
/**
* C语言书籍
*/
public class CBook implements EBook {
@Override
public void read() {
System.out.println("阅读c语言书籍");
}
}
package com.liuyi.designmode.creational.factory;
/**
* 抽象工厂接口
*/
public interface EBookFactory {
public EBook createEBook();
}
package com.liuyi.designmode.creational.factory;
/**
* 创建java语言书籍的具体工厂类
*/
public class EJavaBookFactory implements EBookFactory{
public EBook createEBook(){
EBook eBook = new JavaBook();
return eBook;
}
}
package com.liuyi.designmode.creational.factory;
/**
* 创建C语言书籍的具体工厂类
*/
public class ECBookFactory implements EBookFactory{
public EBook createEBook(){
EBook eBook = new CBook();
return eBook;
}
}
package com.liuyi.designmode.creational.factory;
/**
* 简单工厂模式测试类
*/
public class FactoryTest {
public static void main(String[] args) {
//比如我想读java的书籍
//用java工厂类创建
EBookFactory javaFactory = new EJavaBookFactory();
EBook eBook = javaFactory.createEBook();
eBook.read();
}
}

工厂方法模式在slf4j源码中的运用:

  我们都指定,使用slf4j可以完成不同日志框架的切换,但是用户本身是感觉不到底层日志框架的改变的,因为用户使用日志的方式始终都是这样

public static final Logger logger = LoggerFactory.getLogger(FactoryTest.class);我们来看看slf4j的源码是怎么实现的:

 进入getLogger方法,可以看到一个抽象工厂角色

 

 

进入该工厂接口,可以看到只有一个方法

 

 

 查看该接口的子类:

 

 进入getILoggerFactory方法,可以看到获取具体的工厂类其实用到了简单工厂方法模式,这里具体slf4j是通过什么机制去选择使用哪种日志框架就不讨论了,有兴趣的同学可以自行

去看看。

 

 这里拿到具体的创建工厂,然后创建对应的logger对象,如果需要添加一种日志实现,首先创建一个实现ILoggerFactory的工厂,然后创建一个实现Logger

的日志产品类,就能在不改变用法的前提实现功能的扩展。

工厂方法模式的优点:

  • 灵活性增强,对于新产品的创建,只需要多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

工厂方法模式的缺点:

  • 类的个数容易增多,增加复杂性。
  • 增加了系统的抽象性和理解难度。
  • 抽象产品只能圣餐一种产品,此弊端可使用抽象工厂模式解决。
版权声明
本文为[负重前行的小牛]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/liu-yi/p/13944047.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云