Java设计模式学习——简单工厂
一. 定义与类型
定义:有工程对象决定创建出哪一种产品类的实例
类型:创建型,但不属于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设计模式学习——简单工厂的更多相关文章
- (@WhiteTaken)设计模式学习——简单工厂
最近工作比较忙,所以没有怎么写博客,这几天将集中学习一下(厉风行)讲解的设计模式的相关知识,并对主要的代码进行介绍. 言归正传,接下来介绍最简单也是最基础的简单工厂设计模式. 什么是简单工厂? 简单工 ...
- Java设计模式之简单工厂、工厂方法和抽象工厂
在前面的学习中(参见前面的博客),我们学到了很多OO原则: 封装变化 多用组合,少用继承 针对接口/超类编程,不针对实现编程 松耦合 开闭原则 让我们从一个简单的类开始,看看如何将之改造成符合OO原则 ...
- Java 设计模式01 - 简单工厂模式
先要学习设计模式之前的先看看一些基础 UML类图简单说明 可以先看看我的这篇博客: UML类图简单说明,学习编程思路的必会技能 接下来才是重点,开始我们的旅程吧. 一.UML类图展示 我们要用简单工厂 ...
- Java设计模式学习之工厂模式
在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了.Java 设计模式之工厂模式 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低 ...
- Java设计模式之简单工厂设计模式
简单工厂将业务逻辑部分和界面逻辑部分分离开来,降低了界面逻辑和业务逻辑的耦合度,符合面向对象迪米特法则.下面以一个加法减法运算器为例,各位读者可以自行按照这种设计方式设计出一个小小的运算器. 1.业务 ...
- (1)java设计模式之简单工厂模式
一:简单工厂模式的优点 --->在阎宏博士的<JAVA与模式>一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Fa ...
- java设计模式之简单工厂模式
简单工厂: 简单工厂的优点: 1.去除客户端与具体产品的耦合,在客户端与具体的产品中增加一个工厂类,增加客户端与工厂类的耦合 2.封装工厂类,实现代码平台的复用性,创建对象的过程被封装成工厂类,可以多 ...
- Java设计模式(1)——简单工厂模式
简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式.通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 一.模式中包含的角色及其职责 1.工厂(Creator)角色 简单 ...
- Java 设计模式之 简单工厂模式(静态工厂方法模式)
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的 ...
随机推荐
- mac安装scrapy
Mac自带python2.7,所以直接安装scrapy.默认安装了Xcode总共分以下几步:1.安装 homebrew.wget2.安装pip3.安装scrapy 安装homebrew在termina ...
- JMETER从JSON响应中提取数据
如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...
- P1984 [SDOI2008]烧水问题(具体证明)
传送门 我见过的第二恶心的题,第一是糖果传递... 以下是一堆具体的证明,自己想的,可能考虑不周,不想看也可以直接看结论 首先有一个很显然的贪心,烧开的水要尽量把热量传递出去 所以有一个比较显然的方法 ...
- springBoot实现socketio
https://github.com/mrniko/netty-socketio-demo https://github.com/mrniko/netty-socketio
- docker jvm 占用高的问题定位
定位流程 先使用一些轻便的工具查看总体情况, 如果情况糟糕, 再使用重量级的工具 jstack 查看线程数是否过多 jstat -gc -gcutil 查看gc次数和时间是否过多, 各个分 ...
- Hystrix使用小结
通过服务熔断实现服务降级 @HystrixCommand(fallbackMethod = "reliable", commandProperties = { @HystrixPr ...
- redis常用
redis的key和string类型value限制均为512MB
- linkedlist--lecture-4
1.链表数据结构 内存利用率高:动态分配 2.链表类定义 单向链表节点 public calss ListNode { int val =0; ListNode next = null; public ...
- QT学习小demo之LightMD(MarkDown编辑器)
很早之前就有了写一个类似Windows记事本的想法,加上最近也刚好在学编译原理,所以就想把两者结合起来,于是就打算结合MarkDown,开发一款MarkDown编辑器. 不过由于我之前一直使用的是Ja ...
- centos6安装bochs
安装包 bochs 2.6.8 平台 centos6 前提依赖 yum groupinstall -y "Server Platform Development" "De ...