共计 7762 个字符,预计需要花费 20 分钟才能阅读完成。
写在后面
- 记录学习设计模式的笔记
- 进步对设计模式的灵活运用
学习地址
https://www.bilibili.com/video/BV1G4411c7N4
https://www.bilibili.com/video/BV1Np4y1z7BU
参考文章
http://c.biancheng.net/view/1317.html
我的项目源码
https://gitee.com/zhuang-kang/DesignPattern
10,适配器模式
10.1 适配器模式的定义和特点
适配器模式(Adapter)的定义如下: 将一个类的接口转换成客户心愿的另外一个接口,使得本来因为接口不兼容而不能一起工作的那些类能一起工作。 适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高。
该模式的次要长处如下:
- 客户端通过适配器能够通明地调用指标接口。
- 复用了现存的类,程序员不须要批改原有代码而重用现有的适配者类。
- 将指标类和适配者类解耦,解决了指标类和适配者类接口不统一的问题。
- 在很多业务场景中合乎开闭准则。
其毛病是:
- 适配器编写过程须要联合业务场景全面思考,可能会减少零碎的复杂性。
- 减少代码浏览难度,升高代码可读性,过多应用适配器会使零碎代码变得凌乱。
10.2 适配器模式的构造与实现
10.2.1 适配器模式的构造
- 指标(Target)接口:以后零碎业务所期待的接口,它能够是抽象类或接口。
- 适配者(Adaptee)类:它是被拜访和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或援用适配者的对象,把适配者接口转换成指标接口,让客户按指标接口的格局拜访适配者。
10.2.2 代码实现
10.2.2.1 类适配器模式
Voltage5V 指标接口
package com.zhuang.adapter.classadapter;
/**
* @Classname Voltage5V
* @Description 定义直流电
* @Date 2021/3/21 14:14
* @Created by dell
*/
public interface Voltage5V {
// 定义一个规范充电器来实现
public int output5V();}
Voltage220V
package com.zhuang.adapter.classadapter;
/**
* @Classname Voltage220V
* @Description 创立交流电
* @Date 2021/3/21 14:13
* @Created by dell
*/
public class Voltage220V {public int output220V() {System.out.println("voltage 输入 220 伏");
return 220;
}
}
VoltageAdapter
package com.zhuang.adapter.classadapter;
/**
* @Classname VoltageAdapter
* @Description 创立充电器
* @Date 2021/3/21 14:14
* @Created by dell
*/
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int output5V() {
// 获取交流电 220V
int output220V = output220V();
// 转为 5V
int output5V = output220V / 44;
System.out.println("VoltageAdapter 输入 5 伏");
return output5V;
}
}
Phone
package com.zhuang.adapter.classadapter;
/**
* @Classname Phone
* @Description 手机类
* @Date 2021/3/21 14:15
* @Created by dell
*/
public class Phone {public void charging(Voltage5V voltage5V) {if (voltage5V.output5V() == 5) {System.out.println("电压 5 伏,能够充电");
} else if (voltage5V.output5V() > 5) {System.out.println("电压过大,不能够充电");
}
}
}
Client
package com.zhuang.adapter.classadapter;
/**
* @Classname Client
* @Description 客户端类
* @Date 2021/3/21 14:15
* @Created by dell
*/
public class Client {public static void main(String[] args) {System.out.println("== 类适配器 ==");
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
类适配器模式注意事项和细节
- Java 是单继承机制,所以类适配器须要继承适配者(Adaptee,指 Voltage220V)类,这点算是一个毛病,除此之外还必须要求指标(Target,指 Voltage5V)必须是接口,有肯定局限性;
- 适配者 Voltage220V 类的办法在适配器 VoltageAdapter 类中都会裸露进去,也减少了应用的老本。然而因为其继承了适配者 Voltage220V 类,所以它能够依据需要重写该类的办法,使得适配器 VoltageAdapter 类的灵活性加强了。
10.2.2.2 对象适配器模式
Voltage5V
package com.zhuang.adapter.objectadapter;
/**
* @Classname Voltage5V
* @Description 充电 5V
* @Date 2021/3/21 14:32
* @Created by dell
*/
public interface Voltage5V {
// 定义一个规范充电器来实现
public int output5V();}
Voltage220V
package com.zhuang.adapter.objectadapter;
/**
* @Classname Voltage220V
* @Description 输入 220V 类
* @Date 2021/3/21 14:32
* @Created by dell
*/
public class Voltage220V {public int output220V() {System.out.println("voltage 输入 220 伏");
return 220;
}
}
VoltageAdapter
package com.zhuang.adapter.objectadapter;
/**
* @Classname VoltageAdapter
* @Description 适配器类
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}
@Override
public int output5V() {
// 获取交流电 220V
int output220V = voltage220V.output220V();
// 转为 5V
int output5V = output220V / 44;
System.out.println("VoltageAdapter 输入 5 伏");
return output5V;
}
}
Phone
package com.zhuang.adapter.objectadapter;
/**
* @Classname Phone
* @Description 手机类
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class Phone {public void charging(Voltage5V voltage5V) {if (voltage5V.output5V() == 5) {System.out.println("电压 5 伏,能够充电");
} else if (voltage5V.output5V() > 5) {System.out.println("电压过大,不能够充电");
}
}
}
Client
package com.zhuang.adapter.objectadapter;
/**
* @Classname Client
* @Description 对象适配器测试类
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class Client {public static void main(String[] args) {System.out.println("== 对象适配器 ==");
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
对象适配器模式注意事项和细节
- 对象适配器和类适配器其实算是同一种思维,只不过实现形式不同。
- 依据合成复用准则,应用组合代替继承,所以它解决了类适配器中 VoltageAdapter 必须继承 Voltage220V 的局限性问题,也不再强制要求 Voltage5V 必须是接口。应用老本更低,更灵便。因而,对象适配器模式是适配器模式罕用的一种。
10.2.2.3 接口适配器模式
Animation
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname Animation
* @Description 动画接口
* @Date 2021/3/21 14:47
* @Created by dell
*/
public interface Animation {public void method1();
public void method2();
public void method3();
public void method4();
public void method5();}
AnimationAdapter
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname AnimationAdapter
* @Description 接口适配器类
* @Date 2021/3/21 14:48
* @Created by dell
*/
public class AnimationAdapter implements Animation {
// 全副都空实现
@Override
public void method1() {}
@Override
public void method2() {}
@Override
public void method3() {}
@Override
public void method4() {}
@Override
public void method5() {}
}
JFrameAnimation
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname JFrameAnimation
* @Description 适配器子类
* @Date 2021/3/21 14:49
* @Created by dell
*/
public class JFrameAnimation extends AnimationAdapter {
@Override
public void method1() {System.out.println("method1() 被调用了...");
}
@Override
public void method2() {System.out.println("method2() 被调用了...");
}
}
Client
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname Client
* @Description 客户端类
* @Date 2021/3/21 14:50
* @Created by dell
*/
public class Client {public static void main(String[] args) {JFrameAnimation animation = new JFrameAnimation();
animation.method1();
animation.method2();}
}
10.3 SpringMVC 源码解析
Controller
package com.zhuang.adapter.springmvc;
/**
* @Classname Controller
* @Description springmvc 的 Controller 源码
* @Date 2021/3/21 14:53
* @Created by dell
*/
// 多种 Controller 实现
public interface Controller {
}
class HttpController implements Controller {public void doHttpHandler() {System.out.println("http...");
}
}
class SimpleController implements Controller {public void doSimplerHandler() {System.out.println("simple...");
}
}
class AnnotationController implements Controller {public void doAnnotationHandler() {System.out.println("annotation...");
}
}
DispatchServlet
package com.zhuang.adapter.springmvc;
import java.util.ArrayList;
import java.util.List;
/**
* @Classname DispatchServlet
* @Description springmvc 的 DispatchServlet 源码
* @Date 2021/3/21 14:52
* @Created by dell
*/
public class DispatchServlet {public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
public DispatchServlet() {handlerAdapters.add(new AnnotationHandlerAdapter());
handlerAdapters.add(new HttpHandlerAdapter());
handlerAdapters.add(new SimpleHandlerAdapter());
}
public void doDispatch() {
// 此处模仿 SpringMVC 从 request 取 handler 的对象,// 适配器能够获取到心愿的 Controller
HttpController controller = new HttpController();
// AnnotationController controller = new AnnotationController();
//SimpleController controller = new SimpleController();
// 失去对应适配器
HandlerAdapter adapter = getHandler(controller);
// 通过适配器执行对应的 controller 对应办法
adapter.handle(controller);
}
public HandlerAdapter getHandler(Controller controller) {// 遍历:依据失去的 controller(handler), 返回对应适配器
for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(controller)) {return adapter;}
}
return null;
}
public static void main(String[] args) {new DispatchServlet().doDispatch(); // http...}
}
HandlerAdapter
package com.zhuang.adapter.springmvc;
/**
* @Classname HandlerAdapter
* @Description springmvc 的 HandlerAdapter 源码
* @Date 2021/3/21 14:53
* @Created by dell
*/
/// 定义一个 Adapter 接口
public interface HandlerAdapter {public boolean supports(Object handler);
public void handle(Object handler);
}
// 多种适配器类
class SimpleHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {((SimpleController) handler).doSimplerHandler();}
@Override
public boolean supports(Object handler) {return (handler instanceof SimpleController);
}
}
class HttpHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {((HttpController) handler).doHttpHandler();}
@Override
public boolean supports(Object handler) {return (handler instanceof HttpController);
}
}
class AnnotationHandlerAdapter implements HandlerAdapter {
@Override
public void handle(Object handler) {((AnnotationController) handler).doAnnotationHandler();}
@Override
public boolean supports(Object handler) {return (handler instanceof AnnotationController);
}
}
写在最初
- 如果我的文章对你有用,请给我点个👍,感激你😊!
- 有问题,欢送在评论区指出!💪
正文完