82 | 开源实战三(中):剖析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
《设计模式之美》,新⼈⾸单¥98
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(40)
- 最新
- 精选
- 3SpidersJDK是浅拷贝,Guava使用的是深拷贝。一个复制引用,一个复制值。2020-05-11463
- hhhh猜测jdk中的不变集合保存了原始集合的引用,而guava应该是复制了原始集合的值。2020-05-11122
- 不能忍的地精Guava里面的引用已经是一个新的集合,Jdk里面的引用还是原来的集合2020-05-1111
- 何用我是个特别能关注到细节的人。Memcached 是个开源库,不知道为何好多人都喜欢把它叫做 Memcache,本文也不例外。2020-05-11110
- leezer我觉得我更赞同wrapper类的理解,因为装饰器的主要功能是在原始的类上做功能增强,而代理模式更多关注对非业务功能的关注。通过组合的方式我们能实现更多的Wrapper模式。这时候就不只是算装饰器的设计模式了 。2020-05-117
- 梦倚栏杆老师给这个深拷贝和浅拷贝不是太形象。String 本身就是不可变的。 从这个例子可以看出的是guava 重新创建了list,jdk 是持有的原list的引用。那么guava 有没有进一步的深copy呢?答案是:没有。里面的对象存储的还是引用 也或许老师说的深copy和浅copy只是指collection的引用。2020-05-156
- 辣么大在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-115
- 小晏子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-114
- testjdk是浅拷贝,guava是深拷贝,在修改的时候报错2020-05-114
- FrankunmodifiableList 内部还是使用了Warpper模式,重新实现了某些方法,比如add,remove等,当调用这些方法时,抛出异常,而有些方法还是委托给原始list进行操作,比如get操作。所以这里在原始类添加元素后,使用不jdk的变类可以打印出新添加的元素。而Guava 中的ImmutableList 时采用拷贝的方式将原始集合中的数据拷贝到一个对象数组中,后续原始集合添加,删除元素,其结果都不会影响该ImmutableList。2020-05-112
收起评论