JAVA 设计模式之 工厂模式详解

时间:2022-09-13 19:34:56

一、简单工厂模式

  简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例。属于创建型模式,但它不属于 GOF,23 种设计模式

(参考资料: http://en.wikipedia.org/wiki/Design_Patterns#Patterns_by_Type)。

  简单工厂模式适用于的场景:

    1、适用 于工厂类负责创建的对象较少的场景,

      2、且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心。

  简单工厂模式缺点:

    1、工厂类的职业相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则

    2、不易于扩展过于复杂的产品结构

下面手写一个简单的工厂模式

/**
* @Description 需要实现的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
} /**
* @Description 实现ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure { @Override
public void record() {
System.out.println("录制Java课程!");
}
} /**
* @Description 工厂类 将类的创建过程封装到工厂里面
* @Author Bert
* @Date 2019\5\21 0021
*/
public class CourseFactory {
/**
* @Description 通过name判断,创建对应的对象
* @Date 2019\5\21 0021 23:05
* @Param [name]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create(String name){
if("Java".equals(name))
return new JavaCoure();
if("Python".equals(name))
return new PythonCoure();
else
return null;
}
/**
* @Description //通过类的全路径
* @Date 2019\5\21 0021
* @Param [className]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create1(String className){
try {
if( null != className && !"".equals(className)){
return (ICoure)Class.forName(className).newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
} /**
* @Description 传入一个Class,可以避免输入错误的内容
* @Date 2019\5\21 0021
* @Param [clazz]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create2(Class clazz){
if (null != clazz) {
try {
return (ICoure) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
} /**
* @Description 测试类
* @Author Bert
* @Date 2019\5\21 0021
*/
public class SimpleFactoryTest { public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
/**
* 通过简单的工厂创建
*/
ICoure iCoure = factory.create("Java");//方式1
iCoure.record(); ICoure factory1 = factory.create1("com.bert.simple.factory.JavaCoure");//方式2
factory1.record(); ICoure factory2 = factory.create2(JavaCoure.class);//方式3
factory2.record(); }
}

  简单工厂模式在 JDK 源码也是无处不在 现在我们来举个例子:

/* 里面通过createCalendar(TimeZone zone, Locale aLocale)传入时区、语言  创建不同时区的时间 */
Calendar calendar = Calendar.getInstance();/* getInstance()是一个工厂模式,也是一个单例模式 */ //Calendar 源码
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
} /* getLogger(Class<?> clazz) 典型的工厂模式 */
Logger logger = LoggerFactory.getLogger(SimpleFactoryTest.class);/*也是一个单例*/ //LoggerFactory源码 public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
}
} return logger;
}

二、工厂方法模式

  工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个 接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。属于创建型模式,23中设计模式之一,在工厂方法 模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符 合开闭原则。

/**
* @Description 需要实现的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
} /**
* @Description 实现ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure { @Override
public void record() {
System.out.println("录制Java课程!");
}
} /**
* @Description TODO
* @Author Bert
* @Date 2019\5\21 0021
*/
public class PythonCoure implements ICoure { @Override
public void record() {
System.out.println("录制Python课程!");
}
} /**
* @Description 工厂接口
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface ICoureFactory {
ICoure create();
} /**
* @Description Java方法工厂
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaICoureFactory implements ICoureFactory{
@Override
public ICoure create() {
return new JavaCoure();
}
} /**
* @Description Python方法工厂
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonICoureFactory implements ICoureFactory{
@Override
public ICoure create() {
return new PythonCoure();
}
} /**
* @Description 工厂方法模式测试类
* @Author Bert
* @Date 2019\5\22 0022
*/
public class FactoryMethodTest { public static void main(String[] args) { ICoureFactory iCoureFactory = new JavaICoureFactory();
ICoure iCoure = iCoureFactory.create();
iCoure.record(); PythonICoureFactory iCoureFactory1 = new PythonICoureFactory();
ICoure iCoure1 = iCoureFactory1.create();
iCoure1.record();
}
}

  类图如下:

JAVA 设计模式之 工厂模式详解

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

    1、创建对象需要大量重复的代码

    2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,一个类通过其子类来指定创建哪个对象。

  工厂方法模式的优点:

    1、用户只关系所需产品对应的工厂,无须关心创建细节。

    2、加入新产品符合开闭原则,提高了系统的可扩展性。

  工厂方法模式的缺点:

    1、类的个数容易过多,增加了代码结构的复杂度。

    2、增加了系统的抽象性和理解难度。

三、抽象工厂模式

  抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或者相互依赖对象的接口,无须指定他们具体的类。

  属于创建型设计模式。

  

/**
* @Description 需要实现的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
} /**
* @Description 实现ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure { @Override
public void record() {
System.out.println("录制Java课程!");
}
} /**
* @Description TODO
* @Author Bert
* @Date 2019\5\21 0021
*/
public class PythonCoure implements ICoure { @Override
public void record() {
System.out.println("录制Python课程!");
}
} /**
* @Description 要求所有的工厂都实现这个工厂
* 一个品牌的抽象
* 1、 抽象工厂不符合开闭原则 (在顶层接口中添加的抽象方法,在继承他的类都需要继承)
* 2、扩展性强
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface ICouseeFactory { ICoure createCourse(); Inote createNote(); Ivideo createVideo(); } /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface Inote { } /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface Ivideo { } /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaNote implements Inote{
} /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaVideo implements Ivideo {
} /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonNote implements Inote {
} /**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonVideo implements Ivideo {
} /**
* @Description JAVA 课程实现
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaCourseFactory implements ICouseeFactory { @Override
public ICoure createCourse() {
return new JavaCoure();
} @Override
public Inote createNote() {
return new JavaNote();
} @Override
public Ivideo createVideo() {
return new JavaVideo();
}
} /**
* @Description Python课程实现
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonCourseFactory implements ICouseeFactory { @Override
public ICoure createCourse() {
return new PythonCoure();
} @Override
public Inote createNote() {
return new PythonNote();
} @Override
public Ivideo createVideo() {
return new PythonVideo();
}
} /**
* @Description 抽象工厂 测试类
* @Author Bert
* @Date 2019\5\22 0022
*/
public class AbstactFactoryTest {
public static void main(String[] args) { ICouseeFactory factory = new JavaCourseFactory();
factory.createCourse().record();
factory.createNote();
factory.createVideo(); }
}

  

 

  抽象工厂模式使用场景:

    1、客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。

    2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

    3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体的实现。

  抽象工厂模式优点:

    1、具体产品在应用层代码隔离,无须关系创建细节。

    2、将一个系列的产品族统一到一起创建。

  抽象工厂模式缺点:

    1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

    2、增加了系统的抽象性和理解难度。

Spring 中用到的抽象工厂模式例如:DefaultListableBeanFactory

JAVA 设计模式之 工厂模式详解的更多相关文章

  1. java之简单工厂模式详解

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  2. Java设计模式之状态模式详解

    (本文由言念小文原创,转载请注明出处) 在实际工作中经常遇到某个对象,处于不同的状态有不同行为逻辑.且状态之间可以相互迁移的业务场景,特别是在开发通信协议栈类软件中尤为多见.<设计模式之禅&gt ...

  3. JAVA 设计模式之 原型模式详解

    原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式利用的是克隆的原理,创建新的对象,JDK提供的Cloneable 和JSON. ...

  4. 浅析JAVA设计模式之工厂模式&lpar;一&rpar;

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  5. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  6. 2&period;java设计模式-抽象工厂模式

    抽象工厂模式简介: 每一个模式都是针对某一种问题的解决方案.抽象工厂模式与工厂模式最大的区别在于,工厂模式针对的是一个产品等级结构,而抽象工厂模式面对的是多个产品等级结构,即产品族的概念. 这里讲解一 ...

  7. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  8. 浅析JAVA设计模式之工厂模式&lpar;二&rpar;

    1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...

  9. java设计模式2————工厂模式

    1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展开放,对修改关闭 依赖倒转原则:面向 ...

随机推荐

  1. Salesforce注册开发者账号

    在对Salesforce进行了简单的了解之后,我们现在来注册Salesforce的开发者账号,开始Salesforce的学习 一.注册前的准备 首先点击网址:https://developer.sal ...

  2. 关于jquery 集合对象的 each和click方法的 思考 -&dollar;&lpar;this&rpar;的认识

    1, 很重要的是: each: 是 自动遍历 集合中所有 item的, 是自动的; click: 包括其他所有的 "事件", 如mouseX事件, keyX事件等, 都不是 自动 ...

  3. JVM内存结构、垃圾回收那点事

    翻看电脑的文件夹,无意看到了9月份在公司做的一次分享,浏览了一下"婆婆特",发现自己在ppt上的写的引导性问题自己也不能确切的回答出来,哎,知识这东西,平时不常用的没些日子就生疏了 ...

  4. 创建第一个Hiberntae工程

    一.前言 很久之前已经对Hibernate有所了解,在项目中进行过简单的应用,基本了解hibernate的简单应用,没有深入的了解,来Shine公司*个月了,公司的ORM框架就是用Hiberante ...

  5. WCF之多个终结点

    1.服务端配置如下(一个Service节点下可有多个endpoint,): <system.serviceModel> <services> <service name= ...

  6. hdu3231 &lpar;三重拓扑排序&rpar; 2009 Asia Wuhan Regional Contest Hosted by Wuhan University

    这道题算是我拓扑排序入门的收棺题了,卡了我好几天,期间分别犯了超时,内存溢出,理解WA,细节WA,格式WA…… 题目的意思大概是在一个三维坐标系中,有一大堆矩形,这些矩形的每条棱都与坐标轴平行. 这些 ...

  7. linux TCP头部的构造的简单分析

    TCP的头部的构造是在函数tcp_transmit_skb()中进行的 函数片段如下: /* Build TCP header and checksum it. */ th = tcp_hdr(skb ...

  8. const修饰指针时应注意的问题

    1.指向常量的指针 顾名思义,一个指针指向const对象,则称它为指向常量的指针. ; int* ptr=&a; //错误 const int* ptr=&a; //必须用const来 ...

  9. DB2数据类型(抄袭)

    数字 数据类型        精度          最小值                                        最大值                       smal ...

  10. 703&period; Kth Largest Element in a Stream

    题目来源: https://leetcode.com/problems/kth-largest-element-in-a-stream/ 自我感觉难度/真实难度: 题意: 这个题目的意思解读了半天,没 ...