面试篇七:设计模式
设计模式是一套提高代码的可维护性、扩展性、复用性、可读性、稳定性、健壮性以及安全性,由前人总结出来的一套解决方案。
- 设计模式原则
(1)开闭原则:对扩展开放,对修改关闭。
(2)单一职责原则:类要职责单一,只负责一个功能领域的任务。
(3)里氏替换原则:不要破坏继承体系,所有引用基类对象的地方能够透明地使用其子类的对象。
(4)依赖倒置原则:面向接口编程。抽象不应该依赖于细节,细节应该依赖于抽象。
(5)接口隔离原则:每个接口要职能单一,多个不同领域接口要分成多个接口,不要写成一个总接口。
(6)合成复用原则:优先使用组合和聚合,尽量少使用继承。
(7)迪米特法则:尽量低耦合,也就是一个类尽量少的与其他类发生相互作用。
- 常用的设计模式
- 单例模式
单例模式就是只需要创建一次,在整个应用生命周期都可以一直使用。分为懒汉式和饿汉式。
饿汉式是在初始化的时候就将单例对象创建出来。
懒汉式是在第一次使用的时候,才将单例对象创建出来。懒汉式要保证线程安全,可以使用双重检查锁和静态内部类的方式创建单例对象。
详细说明链接:https://www.cnblogs.com/scorpio-cat/p/12707402.html
- 代理模式
代理模式通常分为静态代理和动态代理(CGLIB动态代理和JDK动态代理)两种,用于功能增强。
静态代理:代理对象持有被代理对象的实例,代理对象和被代理对象实现了同一接口,代理对象在实现方式时,调用被代理对象的方法,并对其进行增强功能处理。
JDK动态代理:基于接口的动态代理实现方式。组成:
1.代理对象实现InvocationHandler接口,持有一个Object对象(目标对象),通过有参构造方法将目标对象注入到代理对象中
2.重写invoke方法并在内部进行功能增强。
3.通过调用反射包下的Proxy.newProxyInstance()来提供一个获取被增强后的代理类。
CGLIB动态代理:基于类的动态代理实现方式。组成:
1.目标类不需要实现接口。
2.代理类实现 net.sf.cglib.proxy.MethodInterceptor接口。
3.代理类中需定义Object目标对象,可通过构造方式或set方式赋值。
4.代理类需实现接口中的 Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)方法。
5.代理类中提供返回增强后的目标对象方法,如getProxy(),其是通过创建增强器Enhancer,设置需要增强的目标对象和回调方法后,调用create()方法来获取到增强后的实例对象。
详细说明链接:https://www.cnblogs.com/scorpio-cat/p/12715222.html
- 责任链模式
责任链模式是用来按责任顺序来处理一系列的事务,由多个节点组成的一条执行链。一个节点处理完业务逻辑后,会根据实际的需求,去传递给下一个节点。如果符合业务处理条件,则会一直执行至最后一个节点处理完成。
下面是两种方式实现:
(1)给每个节点都设置下一个节点处理类,如果最后一个节点没有设置下一节点,则结束。
(2)使用List,将所有的任务节点按顺序放入list中,循环执行调用即可。
详细说明链接:https://www.cnblogs.com/scorpio-cat/p/12732012.html
- 适配器模式
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
类的适配器组成:目标接口、原始类实现目标接口、适配器类实现目标接口并继承原始类。
对象的适配器组成:目标接口、原始类实现目标接口、适配器类实现目标接口并持有原始类实例。
接口的适配器模式:目标接口、原始类实现目标接口、抽象类实现目标接口,适配器类继承抽象类,不直接与原接口打交道。
接口的适配器模式,是我们并不需要原始类的那么多方法,只需要其中部分方法,这时考虑用接口的适配器模式。
- 装饰者模式
装饰者模式是动态地给一个对象添加一些新的功能。组成:装饰者和被装饰者实现同一接口,装饰者持有被装饰者的实例。
- 策略模式
策略模式主要解决的是使用 if...else 所带来的复杂和难以维护。组成:
1.定义一个接口,各种行为都实现同一接口。
2.定义一个容器类,持有接口实现,提供一个方法根据持有的具体实例对象调用接口方法。