海加尔金鹰||弋超帆

记录精彩的程序人生

目录
设计模式学习笔记之适配器模式
/  

设计模式学习笔记之适配器模式

前言

这是一篇学习笔记,内容很多是来源于网上的资料,然后按照自己学习情况进行的总结,有些是自身的感受,有些是网上比较好的资料的引用。

如果有人看到我写的笔记有不对的地方欢迎留言指出来,是真的欢迎指出来,因为我可能会错很久,然后才发现。学习技术不能闭门造车,要多交流,多讨论,多思考才能成长的快,学的快。

我的个人博客:海加尔金鹰

什么是适配器模式

适配器模式的定义

适配器模式有时也称包装器模式,指的是将一个类的接口转换成我们需要的接口。根据不同的实现方式适配器可以分为三种:继承类的叫类适配器,持有类的叫对象适配器,实现接口的叫接口适配器。

适配器模式适用场景

  1. 系统需要使用现有的类,但现有的类却不兼容。
  2. 需要建立一个可以重复使用的类,用于一些彼此关系不大的类,并易于扩展,以便于面对将来会出现的类.
  3. 需要一个统一的输出接口,但是输入类型却不可预知1

适配器模式的结构

  1. 目标接口(Target):调用方所期待得到的接口。
  2. 适配器(Adaper):核心角色,适配器把源接口转换成目标接口。
  3. 被适配者(Adaptee):即真正的接口,需要通过适配器进行调用。

类适配器

被适配者(Adaptee)

public class HQB {
    //源接口,不符合目前的需求需要进行适配修改。
    public String show(String msg){
        return "霍去病:"+msg;
    }
}

目标接口(Target)

public interface HQUBService {
    //客户端希望得到的新的接口
    String newShow(String name,String msg);
}

适配器(Adaper)

public class HQBAdapter extends HQB implements HQUBService {

    @Override
    public String newShow(String name,String msg) {
        //这是原来的接口
        String old = show(msg);
        System.out.println(old);
        //新接口需要在原来的接口上进行部分修改
        String replace = old.replace("霍去病", name);
        return replace;
    }
}

对象适配器

在上述代码基础上新增一个适配器

public class HQBAdapter2 {
    //将被适配者当成属性持有
    private HQB hqb;
    //通过构造器方式注入  不一定使用这种方式,但一定要保证被适配者不为NULL,不然怎么进行适配
    public HQBAdapter2(HQB hqb){
        this.hqb=hqb;
    }

    public void newShow(String name,String msg){
        //原来的处理方式
        String show = hqb.show(msg);
        System.out.println(show);
        //新处理方式
        System.out.println(show.replace("霍去病",name));
    }
}

类适配器和对象适配器的调用方式和结果

调用方式:

public class HQBTest {
    public static void main(String[] args) {
        //类适配器
        String newShow = new HQBAdapter().newShow("两分刘", "真的短");
        System.out.println(newShow);
        //对象适配器
        new HQBAdapter2(new HQB()).newShow("乔碧螺陛下","榜一");
    }
}

结果:

霍去病:真的短
两分刘:真的短
霍去病:榜一
乔碧螺陛下:榜一

类适配器和对象适配器的权衡

  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
  • 对于类适配器由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,当适配器继承了Adaptee后,就不可能再去处理 Adaptee的子类了。
  • 对于对象适配器一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
  • 对于类适配器适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。
  • 对于对象适配器要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
  • 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。
  • 对于对象适配器,需要额外的引用来间接得到Adaptee。

    建议尽量使用对象适配器的实现方式,多用合成或聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。2

接口适配器

当一个接口当中有很多的方法,但是只想实现其中的几个,如果直接实现接口,就需要实现所有的方法,会显得实现类很臃肿,这个时候可以通过一个抽象类来实现接口,将不需要实现的方法置空,然后写一个类来继承抽象类就可以了。

	代码略

个人感觉接口适配器更像一种接口实现的优化方式。
同时如果说一个接口里面有太多的方法,按照设计原则上来说,是应该对这个接口里的方法进行下细分的。

适配器适用场景

1 在不修改原来接口源码的条件下,将原来的接口转换成新的接口。
2 提供一个高重用的类,可以供多处使用。例如一个手机壳,当我去小米公司上班,通过手机壳将手机伪装成小米手机,去华为就伪装成华为手机。但实际上我用的还是诺基亚。

适配器优缺点

优点:提高了复用性以及扩展性
缺点:提高代码复杂性,方法调用不是很直观,明明调用的A,结果调用的是B也可能是C。反正能少用就少用,如果用也要写好注释。

将来的你,一定会感谢现在努力的自己
评论