一. 定义与类型

定义:有工程对象决定创建出哪一种产品类的实例

类型:创建型,但不属于GOF23中设计模式

二. 适用场景

工厂类负责创建的对象比较少

客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心

三. 优点与缺点

优点:只需要传入一个正确的参数,就可以获取你所需要的对象,而无需知道其创建细节

缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则

四. coding

/**
* @program: designModel
* @description: 视频类
* @author: YuKai Fan
* @create: 2018-11-13 16:46
**/
public abstract class Video {
public abstract void product();
}
/**
* @program: designModel
* @description: java视频类
* @author: YuKai Fan
* @create: 2018-11-13 16:47
**/
public class JavaVideo extends Video {
public void product() {
System.out.println("录制java课程视频");
}
}
/**
* @program: designModel
* @description: Python视频类
* @author: YuKai Fan
* @create: 2018-11-13 16:48
**/
public class PythonVideo extends Video{
public void product() {
System.out.println("录制Python课程视频");
}
}
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-11-13 16:48
**/
public class Test {
public static void main(String[] args) {
/*Video video = new JavaVideo();
video.product();*/
VideoFactory videoFactory = new VideoFactory();
Video java = videoFactory.getVideo("java");
if (java == null) {
return;
}
java.product();
}
}

这样,应用层(客户端)只需要传入需要的类型,就可以得到相应的类型视频,不知道创建的细节,UML类图为

但是,如果要新增加一个课程的话,就必须在原有的基础上修改代码,这样违背了设计原则的开闭原则

可以对上面的代码进行一定的改进,通过反射的方法来完成类型的选择

/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-11-13 16:50
**/
public class VideoFactory {
public Video getVideo(Class c) {
Video video = null;
try {
video = (Video) Class.forName(c.getName()).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return video;
} /*public Video getVideo(String type) { if ("java".equalsIgnoreCase(type)) {
return new JavaVideo(); } else if ("python".equalsIgnoreCase(type)) {
return new PythonVideo(); }
return null;
}*/
}
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-11-13 16:48
**/
public class Test {
public static void main(String[] args) {
/*Video video = new JavaVideo();
video.product();*/
/*VideoFactory videoFactory = new VideoFactory();
Video java = videoFactory.getVideo("java");
if (java == null) {
return;
}
java.product();*/
VideoFactory videoFactory = new VideoFactory();
Video java = videoFactory.getVideo(JavaVideo.class);
if (java == null) {
return;
}
java.product();
}
}

这样的好处是,应用层(客户端)直接传入对应的视频类class即可,不需要修改工厂类的代码

五. 源码分析 jdk源码解析

在jdk中使用简单工厂的体现:

1.calender.java中的getInstance方法中的createCalender方法

private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
} Calendar cal = null;

//这里使用的就是简单工厂模式,switch-case判断返回相应的国家日期类型
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.        //这里使用的就是简单工厂模式,if-else判断返回相应的国家日期类型
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}

这个类的UML为:

jdbc中的加载驱动,获取连接,也是用的简单工厂模式

Java设计模式学习——简单工厂的更多相关文章

  1. (@WhiteTaken)设计模式学习——简单工厂

    最近工作比较忙,所以没有怎么写博客,这几天将集中学习一下(厉风行)讲解的设计模式的相关知识,并对主要的代码进行介绍. 言归正传,接下来介绍最简单也是最基础的简单工厂设计模式. 什么是简单工厂? 简单工 ...

  2. Java设计模式之简单工厂、工厂方法和抽象工厂

    在前面的学习中(参见前面的博客),我们学到了很多OO原则: 封装变化 多用组合,少用继承 针对接口/超类编程,不针对实现编程 松耦合 开闭原则 让我们从一个简单的类开始,看看如何将之改造成符合OO原则 ...

  3. Java 设计模式01 - 简单工厂模式

    先要学习设计模式之前的先看看一些基础 UML类图简单说明 可以先看看我的这篇博客: UML类图简单说明,学习编程思路的必会技能 接下来才是重点,开始我们的旅程吧. 一.UML类图展示 我们要用简单工厂 ...

  4. Java设计模式学习之工厂模式

    在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了.Java 设计模式之工厂模式 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低 ...

  5. Java设计模式之简单工厂设计模式

    简单工厂将业务逻辑部分和界面逻辑部分分离开来,降低了界面逻辑和业务逻辑的耦合度,符合面向对象迪米特法则.下面以一个加法减法运算器为例,各位读者可以自行按照这种设计方式设计出一个小小的运算器. 1.业务 ...

  6. (1)java设计模式之简单工厂模式

    一:简单工厂模式的优点          --->在阎宏博士的<JAVA与模式>一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Fa ...

  7. java设计模式之简单工厂模式

    简单工厂: 简单工厂的优点: 1.去除客户端与具体产品的耦合,在客户端与具体的产品中增加一个工厂类,增加客户端与工厂类的耦合 2.封装工厂类,实现代码平台的复用性,创建对象的过程被封装成工厂类,可以多 ...

  8. Java设计模式(1)——简单工厂模式

    简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式.通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 一.模式中包含的角色及其职责 1.工厂(Creator)角色 简单 ...

  9. Java 设计模式之 简单工厂模式(静态工厂方法模式)

    简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的 ...

随机推荐

  1. CTS/APIO2019游记

    退役后游记... 这次是真·游记了 ghj1222自从省选翻车后心情一直不错 5.12 (CTS 报到) 没去thupc(话说都不知道thupc这时候举行),于是就这天从衡水出发了 翻来覆去睡不着觉, ...

  2. thinkphp5.1常量定义使用

    thinkphp5.1取消了系统常量 可以把常量配置在app.php文件中 //配置网站地址 'WEB_URL'=>'http://127.0.0.1/tp5', 可以使用config()函数直 ...

  3. 移动Web开发规范概述

    以下规范建议,均是Alloyteam在日常开发过程中总结提炼出的经验,规范具备较好的项目实践,强烈推荐使用. 字体设置 使用无衬线字体 body { font-family: "Helvet ...

  4. POJ1030 Rating

    题目来源:http://poj.org/problem?id=1030 题目大意:有100支队伍(编号1->100),有两场比赛.以下表的形式列出了两场比赛的名次.(有的队伍没有参赛或只参加了一 ...

  5. 导入别的类中的bean

    @Configuration class CommonContext { @Bean public MyBolt myBolt() { return new MyBolt(); } } ... @Co ...

  6. LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence.Fo ...

  7. (转)linux paste命令用法详解

    linux paste命令用法详解原文:http://www.xfcodes.com/linuxcmd/mulu/10211.htmlinux下paste命令,可用于合并文件的列. 功能说明:合并文件 ...

  8. JVM基础知识2 垃圾收集器与内存分配策略

    如何判断堆中的哪些对象可以被回收 主流的程序语言都是使用根搜索算法(GC Roots Tracing)判定对象是否存活 基本思路是:通过一系列名为“GC Roots”的对象作为起点,从这些节点开始向下 ...

  9. CXF 发布rest服务

    1.1      什么是rest服务 REST 是一种软件架构模式,只是一种风格,rest服务采用HTTP 做传输协议,REST 对于HTTP 的利用实现精确的资源定位. Rest要求对资源定位更加准 ...

  10. Devexpress之GridControl显示序列号

    先上图: 操作方法: 1.先设置一下gridview中属性:IndicatorWidth,一般为:40.如下图:(一般可以显示5位数字.如要更长显示,自己测试一下.) 2.找到gridview中的:C ...