适配器模式和桥接模式
目录
1、适配器模式
1.1 什么是适配器模式
适配器模式又叫变压器模式,就是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。属于结构型设计模式。
1.2 结构图
- 对象适配器模式包含如下角色
- Target(目标抽象类):定义客户所需接口,可以是接口、抽象类或者具体类
- Adapter(适配器):继承实现Target关联Adaptee,完成接口的转换
- Adaptee(适配者):定义存在的接口被适配器适配
- 对象适配器的核心是适配器继承或者实现目标类委派适配者(关联关系)完成任务
- 一个适配器能够适配多个适配者
- 类适配器角色与对象适配器角色一样,区别是类适配器继承适配者
1.3 实例演示
适配器可以分为三种,分别是类适配器,对象适配器,接口适配器。
(1)类适配器的原理是通过继承来实现适配功能。
(2)对象适配器的原理是组合来实现适配功能。
(3)接口适配器的关注点与类适配器和对象适配器的关注点不一样,类适配器和对象适配器注重于系统存在一个角色转换成目标接口所需内容,而接口适配器使用的场景是解决接口过多,如果直接实现接口,那么类会多出许多空实现的方法,类显的很臃肿,此时就可以考虑使用接口适配器。
类适配器实现代码:
/**
* @description: 被适配器者adaptee
* @author: zps
* @create: 2020-05-04 10:52
**/
public class AC220 {
public int output200W(){
System.out.println("输出电压" + "220W");
return 200;
}
}
/**
* 目标接口:Target
*/
public interface DC5 {
int outpurDC5();
}
/**
* @description: 适配者
* @author: zps
* @create: 2020-05-04 10:55
**/
public class PowerAdapter extends AC220 implements DC5 {
@Override
public int outpurDC5() {
int temp = super.output200W();
int res = temp / 44;
System.out.println("适配成功!输入电压5V");
return res;
}
}
/**
* @description: 测试
* @author: zps
* @create: 2020-05-04 10:57
**/
public class Test {
public static void main(String[] args) {
DC5 adapter = new PowerAdapter();
adapter.outpurDC5();
}
}
结果:
对象适配器模式,只需修改适配器代码如下:
/**
* @description: 对象适配器
* @author: zps
* @create: 2020-05-04 11:02
**/
public class PowerAdatper2 implements DC5{
private AC220 ac220;
public PowerAdatper2(AC220 ac220){
this.ac220 = ac220;
}
@Override
public int outpurDC5() {
int temp = ac220.output200W();
int res = temp / 44;
System.out.println("适配成功!输入电压5V");
return res;
}
}
1.4 小结
优点:
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构。
- 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一适配者类可以在多个不同的系统中复用。
- 灵活性和扩展性都非常好,通过使用配置文件,可以很方便的更换适配器,也可以在不修改原有代码的基础上 增加新的适配器,完全复合开闭原则。
缺点:
- 一次最多只能适配一个适配者类,不能同时适配多个适配者。
- 适配者类不能为最终类,在C#中不能为sealed类
- 目标抽象类只能为接口,不能为类,其使用有一定的局限性。
适配器模式在源码中的使用:
- springmvc中有应用
1.5 手写模拟springmvc适配器模式
springmvc的大致处理路程:
- 用户发起请求到前端控制器
- 前端控制器调用处理器映射器根据url找到相应的处理器并返回给前端控制器
- 前端控制器根据处理器的类型调用相应的处理器适配器进行处理,处理完后,返回一个ModelView视图给前端控制器
- 前端控制器调用视图解析器进行解析,并返回视图对象View
- 前端控制器对视图进行渲染会返回给用户即可。
模拟代码实现如下,使用了接口适配器:
/**
* 控制器类行接口
*/
public interface Controller {
void handler();
}
/**
* @description:注解控制器
* @author: zps
* @create: 2020-05-04 11:33
**/
public class AnnotionHandlerController implements Controller {
@Override
public void handler() {
System.out.println("测试注解适配器成功!");
}
}
/**
* @description:Http控制类
* @author: zps
* @create: 2020-05-04 11:38
**/
public class HttpHandlerController implements Controller {
@Override
public void handler() {
System.out.println("测试Http适配器成功");
}
}
/**
* 适配接口
*/
public interface HandlerAdapter {
//判断是否满足适配类型
boolean supports(Object handler);
//处理请求接口
void handler(Object handle);
}
/**
* @description: 注解适配器类
* @author: zps
* @create: 2020-05-04 11:30
**/
public class AnnotionHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof AnnotionHandlerController);
}
@Override
public void handler(Object handle) {
((AnnotionHandlerController)handle).handler();
}
}
/**
* @description: Http适配器
* @author: zps
* @create: 2020-05-04 11:37
**/
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpHandlerController);
}
@Override
public void handler(Object handle) {
((HttpHandlerController)handle).handler();
}
}
/**
* @description: 前端控制器
* @author: zps
* @create: 2020-05-04 11:48
**/
public class DispatcherServlet {
//适配器列表
public List<HandlerAdapter> handlerAdapters;
//初始化适配器
public DispatcherServlet(){
handlerAdapters = new ArrayList<>();
handlerAdapters.add(new AnnotionHandlerAdapter());
handlerAdapters.add(new HttpRequestHandlerAdapter());
}
//调用方法
public void disparcher(Controller controller){
//获取适配器
HandlerAdapter handlerAdapter = getHandlerAdapter(controller);
//进行逻辑处理
handlerAdapter.handler(controller);
}
private HandlerAdapter getHandlerAdapter(Controller controller) {
if(this.handlerAdapters != null){
for(HandlerAdapter h : handlerAdapters){
if(h.supports(controller))
return h;
}
}
return null;
}
}
/**
* @description: 测试
* @author: zps
* @create: 2020-05-04 11:55
**/
public class Test {
public static void main(String[] args) {
HttpHandlerController h = new HttpHandlerController();
DispatcherServlet d = new DispatcherServlet();
d.disparcher(h);
}
}
测试结果: