目录
1、适配器模式(Adapeter Pattern)将某个类的接口转换成客户端期待的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,又称包装器。
2、适配器模式属于结构型模式
3、主要有三种:类适配器模式、对象适配器模式、接口适配器模式。
1、将一个类的接口转换成另一个接口,让原本接口不兼容的类可以兼容。
2、从用户的角度看不到被适配者,是解耦的。
3、用户调用适配器转化出来的目标接口方法,适配器再被适配者的相关接口方法。
4、用户收到反馈结果,只是觉得和目标结果交互。
Adapter类通过继承src类,实现dst类接口,完成适配。
问题需求:220v的交流电需要是充电器适配给需要5v交流电的手机。
示例参考代码:
- //被适配类
- public class Voltage {
- public int output220(){
- int src = 220;
- return src;
- }
- }
- //适配接口
- public interface IVoltage {
- public int output5();
- }
- public class VoltageAdapter extends Voltage implements IVoltage {
-
- @Override
- public int output5() {
- //获取220v
- int srcV = super.output220();
- int dstV = srcV / 44; //转换为5v电压
- return dstV;
- }
- }
- public class Phone {
- //充电
- public void charging(IVoltage iVoltage){
- int src = iVoltage.output5();
- if (src == 5){
- System.out.println("可以正常充电");
- }else {
- System.out.println("不可以正常充电");
- }
- }
- }
- public class Client {
- public static void main(String[] args) {
- Phone phone = new Phone();
- phone.charging(new VoltageAdapter());
- }
- }
代码分析:
1、Java是单继承机制,所以类适配器需要继承Voltage类是一个缺点,因为IVoltage必须是接口,有一定局限性。
2、Voltage类的方法会在VoltageAdapter类暴露出来,增加了使用成本。
3、因为继承了Voltage类,所以可以根据需要重写Voltage类的方法,使VoltageAdapter类更加灵活
1、将VoltageAdapter做修改,不再继承Voltage类,而是持有Voltage类,解决兼容性的问题。
2、根据“合成复用原则”,尽量使用关联关系替代继承关系。
3、对象适配器模式是适配器模式常用一种。
示例参考代码:
其他代码不变,只需要修改这两个类:
- public class VoltageAdapter implements IVoltage {
- private Voltage voltage;
- //通过构造器传入Voltage实例
- public VoltageAdapter(Voltage voltage) {
- this.voltage = voltage;
- }
-
- @Override
- public int output5() {
- int dst = 0;
- if (voltage != null){
- int src = voltage.output220();
- dst = src / 44;
- }
- return dst;
- }
- }
- public class Client {
- public static void main(String[] args) {
- Phone phone = new Phone();
- phone.charging(new VoltageAdapter(new Voltage()));
- }
- }
代码分析:
1、对象适配器与类适配器思想相同,只是实现方式不同。根据合成复用原则,使用组合替代继承,解决了类适配器必须继承的局限性问题,不再要求IVoltage为接口。
2、使用成本更低,更灵活。
1、当不需要全部实现接口提供的方法时,设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
2、适合使用于一个接口不想使用其所有的方法的情况。
示例参考代码:
- public interface Interface1 {
- public void m1();
- public void m2();
- public void m3();
- }
- //对Interface1的方法进行默认实现
- public abstract class AbsAdepter implements Interface1 {
- @Override
- public void m1() {
-
- }
- @Override
- public void m2() {
-
- }
- @Override
- public void m3() {
-
- }
- }
- public class Client {
- public static void main(String[] args) {
- AbsAdepter absAdepter = new AbsAdepter(){
- @Override
- public void m1() {
- super.m1();
- System.out.println("m1方法使用");
- }
- };
- absAdepter.m1();
- }
- }
1、springMVC中的HandlerAdapter中使用
当请求过来时会在DispatcherServlet调用doDispatch方法
mappedHandler相当于控制器,通过mappedHandler调用getHandler方法返回一个适配器
在这里会返回一个适配器
通过得到的适配器调用handle方法。
模拟springmvc通过适配器获取对应controller的源码
参考代码实现:
- //多种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...");
- }
- }
- //定义一个Adepter接口
- public interface HandlerAdepter {
- public boolean supports(Object handler);
- public void handler(Object handler);
- }
- //多种适配器类
- class SimpleHandlerAdepter implements HandlerAdepter{
-
- @Override
- public boolean supports(Object handler) {
- return (handler instanceof SimpleController);
- }
-
- @Override
- public void handler(Object handler) {
- ((SimpleController) handler).doSimplerHandler();
- }
- }
- class AnnotationHandlerAdepter implements HandlerAdepter{
-
- @Override
- public boolean supports(Object handler) {
- return (handler instanceof AnnotationController);
- }
-
- @Override
- public void handler(Object handler) {
- ((AnnotationController) handler).doAnnotationHandler();
- }
- }
- class HttpHandlerAdepter implements HandlerAdepter{
-
- @Override
- public boolean supports(Object handler) {
- return (handler instanceof HttpController);
- }
-
- @Override
- public void handler(Object handler) {
- ((HttpController) handler).doHttpHandler();
- }
- }
- public class DispatchServlet {
- public static void main(String[] args) {
- new DispatchServlet().doDispatch();
- }
- public static List
handlerAdepters = new ArrayList<>(); -
- public DispatchServlet() {
- handlerAdepters.add(new AnnotationHandlerAdepter());
- handlerAdepters.add(new HttpHandlerAdepter());
- handlerAdepters.add(new SimpleHandlerAdepter());
- }
- public void doDispatch(){
- //模拟SpringMVC从request取handler的对象
- //适配器可以获取到希望的controller
- AnnotationController annotationController = new AnnotationController();
- //得到对应的适配器
- HandlerAdepter handler = getHandler(annotationController);
- //通过适配器执行对应的controller代码
- handler.handler(annotationController);
- }
- public HandlerAdepter getHandler(Controller controller){
- for (HandlerAdepter adepter: this.handlerAdepters) {
- if (adepter.supports(controller)){
- return adepter;
- }
- }
- return null;
- }
- }
1、springMVC定义一个适配器接口,使得每一种Controller有一种对应的适配器实现类适配器代替controller执行相应的方法。
2、在扩展Controller时,只需要增加一个适配器类就完成了springMVC的扩展。
1、三种命名方式,是根据src是以怎样的形式给到Adapter来命令。
2、类适配器:以类给到,在Adapter里,就是将src当做类,继承。
对象适配器:以对像给到,在Adapter里 ,将src作为一个对象,持有。
接口适配器:以接口给到。在Adapter里,将src作为一个接口,实现。
3、Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。