设计模式
JDK中有哪些设计模式
设计模式:四人帮GOF于1994年提出。什么是 GOF(四人帮:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides,全拼 Gang of Four)
-
结构性模式
-
适配器模式
把一个接口转化为另一个接口。比如美国110v,中国220v,则需要一个适配器转换电压。
-
java.util.Arrays#asList 体现的是适配器模式,只是转换接口
/* asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。 Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。 */ String[] str = new String[]{"1", "2"}; List<String> list = Arrays.asList(str); list.add("1"); // add/remove/clear方法会抛出UnsupportedOperationException list.set(0, "10"); // 可以修改 str[0] = "10"; // 也是可以的 // 坑 int[] ints = new int[]{1, 2}; List<int[]> list = Arrays.asList(ints); list.size(); // 1, int[]改成Integer[],以及List<Integer>,就是2了 list.add(1); // 直接无法编译,因为基本类型是不能做泛型参数的,改成Integer就行了
-
java.io.InputStreamReader(InputStream)
-
为JDK1.1的Enumeration写适配JDK1.2的Iterator的适配器IteratorAdapter
//父类接口为泛型参数,这里保持一致 public class IteratorAdapter<E> implements Enumeration<E> { Iterator<E> iterator; public IteratorAdapter(Iterator<E> iterator) { this.iterator = iterator; } @Override public boolean hasMoreElements() { return iterator.hasNext(); } @Override public E nextElement() { return iterator.next(); } }
-
-
桥接模式
将抽象和抽象的具体实现进行解耦,这样可以使得抽象和抽象的具体实现可以独立进行变化。
- JDBC:一个接口,由各个数据库产品厂商去完成具体实现,由JDBC将数据库操作功能和JAVA代码桥接起来,则只需要考虑具体业务逻辑即可。
-
组合模式
用于把一组相似的对象当作一个单一的对象,换句话说,某个类型的方法同时也接受自身类型作为参数。常用在级联操作的优化上,比如后台管理系统,树形级联菜单,删除父菜单需要级联删除其子菜单,可以使用这个设计模式;又比如算术表达式,运算符,左右可以是运算符,也可以是操作数。
- List#addAll
-
装饰者模式
动态的给对象附加额外功能,但不改变类原有结构,减少不必要的子类编写扩展行为。使用广泛,如aop编程。
- xxxInputStream如BufferedInputStream,内包含一个InputStream对象,但利用InputStream原有的方法,加入了自己特殊的操作方式,即对InputStream进行了包装。
-
门面模式
给一组组件,接口,抽象,或者子系统提供一个简单的接口。
- java.lang.Class
-
享元模式
使用缓存来加速大量小对象的访问时间。
- java.lang.Integer#valueOf(int)
-
代理模式
代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象。
- java.lang.reflect.Proxy
-
-
创建模式
-
抽象工厂模式
一个创建新对象的方法,返回的却是接口或者抽象类的,就是抽象工厂模式了。好处是解耦,如Spring创建bean
- java.util.Calendar#getInstance()
- java.util.Arrays#asList()
- Spring中的BeanFactory :BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D://applicationContext.xml"));
- ApplicationContext 是BeanFactory 的子接口。ApplicationContext applicationContext = new ClassPathXmlApplicationContext("D://applicationContext.xml");
-
建造者模式
通过定义一个类来简化复杂对象的创建,该类的目的是构建另一个类的实例。比如订单类很复杂,于是就可以用建造者模式创建订单。
- java.lang.StringBuilder#append()
- java.sql.PreparedStatement
-
工厂方法
就是一个返回具体对象的方法。
- java.lang.Proxy#newProxyInstance()
- java.lang.Object#toString()
-
原型模式
使得类的实例能够生成自身的拷贝。如果创建一个对象的实例非常复杂且耗时时,就可以使用这种模式,而不重新创建一个新的实例,你可以拷贝一个对象并直接修改它。并不冷门,比如我们业务代码,经常要各种DTO、BO、DO、VO转换,其实就可以参考原型设计模式的思想来做。
- java.lang.Object#clone()
- java.lang.Cloneable
-
单例模式
用来确保类只有一个实例。可以用枚举。Spring容器中大部分的bean都是单例的。
- java.lang.Runtime#getRuntime()
-
-
行为模式
-
责任链
通过把请求从一个对象传递到链条中下一个对象的方式,直到请求被处理完毕,以实现对象间的解耦。比如mybatis、SpringMVC中的拦截器
- java.util.logging.Logger#log()
- javax.servlet.Filter#doFilter()
-
观察者模式
它使得一个对象可以灵活的将消息发送给感兴趣的对象。比如Zookeeper来观察链路调用,又比如分布式锁、服务发现
- java.util.EventListener
- javax.servlet.http.HttpSessionBindingListener
-
策略模式
使用这个模式来将一组算法封装成一系列对象。通过传递这些对象可以灵活的改变程序的功能。常用于优化大量if-else
- java.util.Comparator#compare()
- javax.servlet.Filter#doFilter()
-
模板方法模式
让子类可以重写方法的一部分,而不是整个重写,你可以控制子类需要重写那些操作。将某些固定重复的操作提取出来做成模板,比如RedisTemplate、JDBCTemplate、RestTemplate
- java.util.Collections#sort()
- java.io.InputStream#read()
-
命令模式
将操作封装到对象内,以便存储,传递和返回。
- java.lang.Runnable
-
解释器模式
这个模式通常定义了一个语言的语法,然后解析相应语法的语句。
- java.util.Pattern(正则表达式)
- java.text.SimpleDateFormat
-
迭代器模式
提供一个一致的方法来顺序访问集合中的对象,这个方法与底层的集合的具体实现无关。
- java.util.Iterator
- java.util.Enumeration
-
中介者模式
通过使用一个中间对象来进行消息分发以及减少类之间的直接依赖。比如MQ消息队列
- java.util.Timer
- java.util.concurrent.Executor#execute()
-
备忘录模式
生成对象状态的一个快照,以便对象可以恢复原始状态而不用暴露自身的内容。比如Date对象通过自身内部的一个long值来实现备忘录模式。
- java.util.Date
- java.io.Serializable(SerializeID来区分版本问题)
-
空对象模式
这个模式通过一个无意义的对象来代替没有对象这个状态。它使得你不用额外对空对象进行处理。
- java.util.Collections#emptyList()
- java.util.Collections#emptyMap()
-
状态模式
通过改变对象内部的状态,使得你可以在运行时动态改变一个对象的行为。比如订单状态
- java.util.Iterator
-
访问者模式
提供一个方便的可维护的方式来操作一组对象。它使得你在不改变操作的对象前提下,可以修改或者扩展对象的行为。用得不多
- javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
-