JAVA 设计模式之 工厂模式详解
Posted bert227
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 设计模式之 工厂模式详解相关的知识,希望对你有一定的参考价值。
一、简单工厂模式
简单工厂模式(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(); } }
类图如下:
工厂方法模式的适用场景:
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 设计模式之 工厂模式详解的主要内容,如果未能解决你的问题,请参考以下文章
Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)