结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂
三种工厂模式的详解:
缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的开闭原则,且产品类多的话,就会使得简单工厂类比较复杂
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;
/*根据不同的地区来创建不同的日历对象,就好比日历这个工厂,生产着世界上各地区的日历,我需要这个地区日历,我只需要传参数告诉工厂即可,不需要知道日历制作过程和实例的过程*/
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 (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;
}
拿其中ArrayList实现的iterator()方法来看
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
可以这样理解:Collection接口里面定义了许多方法就像size(),isEmpty(),iterator()等等这些方法可以认为是工厂里面的产品,Collection可以看作是一个总的抽象工厂。它的一些实现这个接口的类,像ArrayList,LinkedHashSet等等可以看作一个个不同的品牌的工厂,而总的产品Iterator接口里面会定义产品所需功能的细节,然后在交给各个品牌不同的工厂来实现。
抽象工厂模式:
看懂上面的之后就特别好理解抽象工厂,抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;(比如Iterator()方法的不同实现)而抽象工厂模式则需要面对多个产品等级结构(Collection接口下的不同方法)。再说明白一点就是:Collection就是一个抽象工厂,它提供了一个产品类的库,所有产品都以同样接口出现,从而使客户端不依赖于具体实现。工厂方法则是抽象工厂里面的其中一个产品类,并且把这个方法的实例化放入具体的实现类中
结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂的更多相关文章
- 结合JDK源码看设计模式——单例模式
定义: 保证一个类仅有一个实例,并提供一个全局访问点 适用场景: 确保任何情况下这个对象只有一个实例 详解: 私有构造器 单利模式中的线程安全+延时加载 序列化和反序列化安全, 防止反射攻击 结合JD ...
- 结合JDK源码看设计模式——桥接模式
前言: 在我们还没学习框架之前,肯定都学过JDBC.百度百科对JDBC是这样介绍的[JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Jav ...
- 结合JDK源码看设计模式——原型模式
定义: 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.不需要知道任何创建的细节,不调用构造函数适用场景: 类初始化的时候消耗较多资源 new产生的对象需要非常繁琐的过程 构造函数比较 ...
- 结合JDK源码看设计模式——模板方法模式
前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...
- 结合JDK源码看设计模式——迭代器模式
前言: Iterator翻译过来就是迭代器的意思.在前面的工厂模式中就介绍过了iterator,不过当时介绍的是方法,现在从Iterator接口的设计来看,似乎又是一种设计模式,下面我们就来讲讲迭代器 ...
- 结合JDK源码看设计模式——适配器模式
定义: 将一个类的接口转换成客户期望的另外一个接口(重点理解适配的这两个字),使得接口不兼容的类可以一起工作适用场景: 已经存在的类,它的方法和需求不匹配的时候 在软件维护阶段考虑的设计模式 详解 首 ...
- 结合JDK源码看设计模式——建造者模式
概念: 将一个复杂对象的构建与它的表示分离.使得同样构建过程可以创建不同表示适用场景: 一个对象有很多属性的情况下 想把复杂的对象创建和使用分离 优点: 封装性好,扩展性好 详解: 工厂模式注重把这个 ...
- 结合JDK源码看设计模式——享元模式
前言 在说享元模式之前,你一定见到过这样的面试题 public class Test { public static void main(String[] args) { Integer a=Inte ...
- 结合JDK源码看设计模式——观察者模式
前言: 现在我们生活中已经离不开微信,QQ等交流软件,这对于我们来说不仅是交流,更有在朋友圈中或空间中进行分享自己的生活,同时也可以通过这个渠道知道别人的生活.我们在看朋友圈的时候其实我们扮演的就是一 ...
随机推荐
- JavaWeb学习路线
一.三大组件介绍 javaweb在开发中有三大组件分别提供不同的功能,这三大组件为servlet,filter,listener 1.servlet 简单来说就是客户端请求服务器和接受服务器的响应,狭 ...
- 实战深度学习OpenCV(二):读取并播放本地或者摄像头的视频
一.读取并播放的代码如下: #include "pch.h" #include <iostream> #include <opencv2/core/core.hp ...
- 【错误解决】Intellj(IDEA) warning no artifacts configured
: warning no artifacts configured,,上面木有Artifacts的选项,,好尴尬, [解决方案]artifacts,是maven中的概念(项目是maven项目),由于没 ...
- React Native 填坑之神奇的报错,已解决
下面对报错进行一下详细描述: 在debug时,点着点着,就会发生: 1.手机显示如下 : Attempted to transition from state `RESPONDER_INACTIVE_ ...
- [Swift]LeetCode862. 和至少为 K 的最短子数组 | Shortest Subarray with Sum at Least K
Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K. If there ...
- Python - Python2与Python3的区别、转换与兼容
区别 Python2.x与Python3.x版本区别:http://www.runoob.com/python/python-2x-3x.html 示例解读Python2和Python3之间的主要差异 ...
- 使用google搜索时的10个小技巧!
为大家分享一些google的技巧,很多工作了好几年的同学还不知道如何高效的利用这些技巧,希望同学们掌握!此为google的技巧,百度现在也基本上都实现了这些功能. 使用搜索引擎的10个搜索技巧 ...
- JavaScript 正则表达式全面总结
本文适合有 JavaScript 基础 && 面向搜索引擎书写正则的人群. 正则表达式是用于匹配字符串中字符组合的模式.正则表达式的模式规则是由一个字符序列组成的.包括所有字母和数字在 ...
- 【Scala篇】--Scala中集合数组,list,set,map,元祖
一.前述 Scala在常用的集合的类别有数组,List,Set,Map,元祖. 二.具体实现 数组 1.创建数组 new Array[Int](10) 赋值:arr(0) = xxx Array[ ...
- SignalR学习笔记(三)Self-Host
SignalR可以借助Owin摆脱对IIS的依赖,实现Self-Host,使得SignalR有了部署在非Windows平台的可能. 什么是Owin Owin的英文全称是Open Web Interfa ...