Loading

适配器模式

前言:

看到适配器我就立马想到了学校的机房的插座为什么都是两个脚的,而我的笔记本插头是三个角的,这就导致了很尴尬的局面,接口不对我充不到电。。试想假如这个时候有一个插头转换器就好了,没错这里的转换器就是适配器,适配器模式也叫转换器模式

 

适配器模式:

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

 

解决了什么问题:

简单来说,就是需要的东西就在眼前,但却不能使用,而短时间又无法改造它,于是我们就想办法去适配它。比如插头转换器就是一种适配器,或者笔记本变压器也是一种适配器,适配器模式只是一种无可奈何的一种补救方式,所以在系统设计的时候请忘记它

 

适配器模式结构图是长这样的(对象适配器)

 

适配器模式结构图是长这样的(类适配器)

 

 

 

 适配器的实现

主要分为两种方式,一种是类适配器,而另一种是对象适配器

类适配器非常简单,因为它面向的是目标是接口,为什么是接口,因为JAVA不支持多继承,如果需要适配的方法是在一个类中的话,还好,但是如果是多个类就无法玩了,所以需要的适配的方法一定是在接口中或者单个类中,言归正转,现在只要我们写一个适配器,其实就是写一个类,这个适配器类只要继原来的接口实现类,然后实现目标接口就写完了

假设我们有如下需求

//原来的目标类
public class A{
        public void sayHi(){
                 System.out.print("HI");
        }
}

//原来的客户端
public class Client{
    
        public static void main(String[] args){
                    A a=new A();
                    a.sayHi();
        }
}

//现在需求变更,不能sayHi,需要用到另一个接口的某个方法,而这个接口本身和目标类是没有关系的,即实现类A和接口B是没有关系的,这时候假如需要用到B接口中说你好的方法

有人会想,这不是很简单吗,直接在A类中实现B不就得了,想法是没有错的,但是这样做相当于修改了源代码,违背了我们设计原则,只拓展不修改

所以要解决这个问题,可以采用适配器模式来解决

刚刚说过了,类适配器的目标是接口
我们需要新增一个适配器类来适配客户端

public inteface B{
  
  //需要适配的方法
  你好();
}

//然后我们的自己写的适配类
public class adapterA extends A implements B{
  //这里需要实现B中未实现的方法
  你好(){
    Systen.out.println("你好");
  }
}

public class Client{    
        public static void main(String[] args){
                    B a=new adapterA();
                    a.sayHi();//既可以调用原来的方法,因为继承了原来的目标类A
            a.你好();//也可以调用适配的方法,同时是没有对A进行改动的也没有对B接口改动
        }
}

 

下面讲解对象适配器

这个对象适配器是针对刚刚假如需要适配多个类的方法给出的一种解决方案,采用的方式是组合(通过在内部包装一个或多个Adaptee对象,把源接口转换成目标接口)

 

 

 

例如这个类图

翻译者相当于一个适配器

public class Translator extends Player{
        //组合需要适配的类
        private ForeignCenter fc=new ForeignCenter();
        。。。

        //覆盖原来有方法,使用适配的类对象
        public void Attack(){
                fc.attack();
        }
        public void Defense(){        
             fc.defense();
     }
}      

 

还有一种冷门叫缺省适配器:

一般是为了弥补接口过大所犯下的过错

实现一个接口的子类,很可能出现很多方法是空着的情况,因为你的接口设计的过大,导致接口中原本不该出现的方法出现了,结果现在子类根本用不上这个方法,但由于JAVA语言规则的原因,实现一个接口必须实现它的全部方法,所以我们的子类不得不被迫写一堆空方法在那,只为了编译通过。

假如我们能够创造一个接口的默认实现类,它里面都是一些默认的方法,当然这里因为没什么可写的就空着了,实际当中可能会加入一些默认情况下的操作,比如如果方法返回结果整数,那么我们在缺省适配器中可以默认返回个0。

只要继承这个默认的适配器(DefaultPerson),然后覆盖掉需要用到的的方法就行了,由于适配器帮我们提供了默认的实现,所以就不需要再写了。但是这样就浪费了一个继承的位置

 

以上

 

posted @ 2018-05-28 17:23  卓庆森  阅读(395)  评论(0编辑  收藏  举报