设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123426 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

82 | 开源实战三(中):剖析Google Guava中用到的几种设计模式

Immutable模式
Wrapper模式
Builder模式
JDK不变集合与Google Guava不变集合的区别
学习设计模式对源码理解的帮助
阅读源码时的质疑精神
Google Guava中使用的设计模式
课堂讨论
重点回顾
学习内容
总结

该思维导图由 AI 生成,仅供参考

上一节课,我们通过 Google Guava 这样一个优秀的开源类库,讲解了如何在业务开发中,发现跟业务无关、可以复用的通用功能模块,并将它们从业务代码中抽离出来,设计开发成独立的类库、框架或功能组件。
今天,我们再来学习一下,Google Guava 中用到的几种经典设计模式:Builder 模式、Wrapper 模式,以及之前没讲过的 Immutable 模式。
话不多说,让我们正式开始今天的学习吧!

Builder 模式在 Guava 中的应用

在项目开发中,我们经常用到缓存。它可以非常有效地提高访问速度。
常用的缓存系统有 Redis、Memcache 等。但是,如果要缓存的数据比较少,我们完全没必要在项目中独立部署一套缓存系统。毕竟系统都有一定出错的概率,项目中包含的系统越多,那组合起来,项目整体出错的概率就会升高,可用性就会降低。同时,多引入一个系统就要多维护一个系统,项目维护的成本就会变高。
取而代之,我们可以在系统内部构建一个内存缓存,跟系统集成在一起开发、部署。那如何构建内存缓存呢?我们可以基于 JDK 提供的类,比如 HashMap,从零开始开发内存缓存。不过,从零开发一个内存缓存,涉及的工作就会比较多,比如缓存淘汰策略等。为了简化开发,我们就可以使用 Google Guava 提供的现成的缓存工具类 com.google.common.cache.*。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Google Guava中使用了Builder模式、Wrapper模式和Immutable模式。Builder模式应用于CacheBuilder类创建Cache对象,避免构造函数参数列表过长,通过Builder模式进行参数校验。Wrapper模式通过Forwarding类实现,提供了一系列缺省的Forwarding类,用户在实现自己的Wrapper类时,可以基于缺省的Forwarding类来扩展,只需实现关心的方法。文章详细介绍了这些设计模式在Google Guava中的应用,为读者提供了深入的技术理解和实践指导。 此外,文章还介绍了Immutable模式在Google Guava中的应用。不变模式指的是对象的状态在创建之后不再改变,可以分为普通不变模式和深度不变模式。Google Guava提供了不变集合类,对象不会增删,但成员变量是可以改变的。与Java JDK提供的不变集合类相比,Google Guava的不变集合类在原始集合增加数据后,不变集合的数据并没有增加,这是两者最大的区别。 总的来说,本文通过代码示例和解释,深入讲解了Builder模式、Wrapper模式和Immutable模式在Google Guava中的应用,同时强调了对源码的深入理解和质疑精神的重要性。文章内容丰富,适合读者快速了解Google Guava中的设计模式应用,以及在多线程环境下的使用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(40)

  • 最新
  • 精选
  • 3Spiders
    JDK是浅拷贝,Guava使用的是深拷贝。一个复制引用,一个复制值。
    2020-05-11
    4
    63
  • hhhh
    猜测jdk中的不变集合保存了原始集合的引用,而guava应该是复制了原始集合的值。
    2020-05-11
    1
    22
  • 不能忍的地精
    Guava里面的引用已经是一个新的集合,Jdk里面的引用还是原来的集合
    2020-05-11
    11
  • 何用
    我是个特别能关注到细节的人。Memcached 是个开源库,不知道为何好多人都喜欢把它叫做 Memcache,本文也不例外。
    2020-05-11
    1
    10
  • leezer
    我觉得我更赞同wrapper类的理解,因为装饰器的主要功能是在原始的类上做功能增强,而代理模式更多关注对非业务功能的关注。通过组合的方式我们能实现更多的Wrapper模式。这时候就不只是算装饰器的设计模式了 。
    2020-05-11
    7
  • 梦倚栏杆
    老师给这个深拷贝和浅拷贝不是太形象。String 本身就是不可变的。 从这个例子可以看出的是guava 重新创建了list,jdk 是持有的原list的引用。那么guava 有没有进一步的深copy呢?答案是:没有。里面的对象存储的还是引用 也或许老师说的深copy和浅copy只是指collection的引用。
    2020-05-15
    6
  • 辣么大
    在JDK中只是将list的地址赋给了UnmodifiableList final List<? extends E> list; UnmodifiableList(List<? extends E> list) { super(list); this.list = list; } 在Guava中不可变集合是“保护性”拷贝,创建的不可变集合可以理解为常量。 要创建真正的不可变集合,集合中的对象还要是真正的不可变。 下面我举个反例,各位看看: public static void main(String[] args) { List<Student> ori = new ArrayList<>(); ori.add(new Student("xiaoqiang", 10)); Student mutable = new Student("wangz", 8); ori.add(mutable); ori.add(new Student("lameda", 12)); List<Student> jdkCopy = Collections.unmodifiableList(ori); List<Student> guavaCopy = ImmutableList.copyOf(ori); ori.add(new Student("wawa", 20)); System.out.println(jdkCopy); System.out.println(guavaCopy); mutable.name = "mutable"; System.out.println(guavaCopy); // [Student{age=10, name='xiaoqiang'}, Student{age=8, name='mutable'}, Student{age=12, name='lameda'}] }
    2020-05-11
    5
  • 小晏子
    JDK中的unmodifiableList的构造函数是对原始集合的浅拷贝,而Guava.ImmutableList.copyOf是对原始集合的深拷贝。从source code可以看出来: UnmodifiableList UnmodifiableList(List<? extends E> list) { super(list); this.list = list; } Guava.ImmutableList.copyOf public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) { if (elements instanceof ImmutableCollection) { @SuppressWarnings("unchecked") // all supported methods are covariant ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList(); return list.isPartialView() ? ImmutableList.<E>asImmutableList(list.toArray()) : list; } return construct(elements.toArray()); } /** Views the array as an immutable list. Checks for nulls; does not copy. */ private static <E> ImmutableList<E> construct(Object... elements) { return asImmutableList(checkElementsNotNull(elements)); } /** * Views the array as an immutable list. Does not check for nulls; does not copy. * * <p>The array must be internally created. */ static <E> ImmutableList<E> asImmutableList(Object[] elements) { return asImmutableList(elements, elements.length); } /** * Views the array as an immutable list. Copies if the specified range does not cover the complete * array. Does not check for nulls. */ static <E> ImmutableList<E> asImmutableList(Object[] elements, int length) { switch (length) { case 0: return of(); case 1: return of((E) elements[0]); default: if (length < elements.length) { elements = Arrays.copyOf(elements, length); } return new RegularImmutableList<E>(elements); } }
    2020-05-11
    4
  • test
    jdk是浅拷贝,guava是深拷贝,在修改的时候报错
    2020-05-11
    4
  • Frank
    unmodifiableList 内部还是使用了Warpper模式,重新实现了某些方法,比如add,remove等,当调用这些方法时,抛出异常,而有些方法还是委托给原始list进行操作,比如get操作。所以这里在原始类添加元素后,使用不jdk的变类可以打印出新添加的元素。而Guava 中的ImmutableList 时采用拷贝的方式将原始集合中的数据拷贝到一个对象数组中,后续原始集合添加,删除元素,其结果都不会影响该ImmutableList。
    2020-05-11
    2
收起评论
显示
设置
留言
40
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部