一. 定义与类型

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

类型:创建型,但不属于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. Tomcat&Servlet

    Tomcat&Servlet 一.web开发相关的概念 1. 软件架构 1.1 C/S架构 C:Client客户端, S:Server服务器 比如:QQ.微信.大型网游 优点: 显示效果炫 安 ...

  2. git分支主干

    ~/Desktop/work/movies/movie(apps) $ git status  //先查看是否有需要提交的东西# On branch appsnothing to commit (wo ...

  3. NYOJ247 虚拟城市之旅 (spfa)

    题目链接:点击打开链接 虚拟的城市之旅 时间限制: ms  |  内存限制: KB 难度: 描述 展馆是未来城市的缩影,个人体验和互动是不变的主题.在A国展馆通过多维模式和高科技手段,引领参观者在展示 ...

  4. CF10D/POJ2127 LCIS解题报告

    题目传送门(洛谷)(CF)(POJ) 前言 期末考试前的最后一篇题解,希望期末考  rp++ 奇怪,为什么在CF上能过的代码到POJ上就 听取WA声一片  (不管了) 题目思路 LCIS模版O(n²) ...

  5. 关于JS的Date对象的探究

    一次代码审核,其中刚好遇见了一些知识点~记录顺带整理一下吧~ date对象是javascript语言中内置的数据类型,用于提供日期和时间的操作接口. Date类型使用自UTC1970年1月1日0点开始 ...

  6. POJ 3537 Crosses and Crosses(sg博弈)

    题目:在1*n 的棋盘里面,A和B都在里面画叉 , 如果谁可以画了一个叉后,可以连成3个叉,那谁胜利 : 分析: 首先考虑如果我在玩游戏,我最希望对手可以画出-x-x or  -xx-   ,  这种 ...

  7. 根据不同环境配置pom

    clean install clean package -P jt808_dev clean package -P tanway_test -X gps-parent <?xml version ...

  8. 022 Generate Parentheses 生成括号

    给 n 对括号,写一个函数生成所有合适的括号组合.比如,给定 n = 3,一个结果为:[  "((()))",  "(()())",  "(())() ...

  9. centos 6 设置无密码登录ssh 不成功问题

    由于需要配置一台git 服务器,所以当时就建立了个git 帐号,之后执行mkdir .ssh   之后在客户端  scp 了自己的pub公钥到.ssh 目录下,但是怎么都还是需要自己再次输入密码,将这 ...

  10. ASP.NET Core模块化前后端分离快速开发框架介绍之4、模块化实现思路

    源码 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com 账户:admin 密码:admin 前 ...