java设计模式--适配器模式

适配器模式

  适配器模式属于设计模式中的结构型模式,主要是为了将一个类的接口转换成客户需要的接口,同时适配器模式使得原本可能接口不兼容的类一起协同工作。

 

适配器模式的适用性

  • 适配器模式适用于原本某一个类提供的接口不足够支撑你目前的需求的时候。

  • 适配器模式适用于想创建一个可复用的类,该类可以与一系列不想关的类或者在未来可能会创建的类协同工作的时候。

  •  适配器模式适用于想使用一批已经存在的子类,但是不可能为每个子类都进行子类化去匹配他们的接口的情形。

 

适配器模式的结构图

  适配器有两种不同的实现方式,分别为类适配器和对象适配器:

类适配器

 

                                         

 

对象适配器

 

                                               

适配器模式中主要分为以下三类角色:

  1. Target(目标角色):定义Client所期待的接口方法。

  2. Adaptee(源角色):目前系统中已经存在的接口,并且该接口等待适配。

  3. Adapter(适配角色):对源角色所提供的接口进行适配转换成目标接口。

  

  由结构图可以看出,不论是类适配器还是对象适配器都是通过Adapter角色对Adaptee角色所提供的接口进行适配,只不过类适配器是通过继承的方式进行适配,这种方式使得Adapter类可以重写Adaptee类中提供的接口但是不能够兼容对Adaptee类的所有子类进行适配;而对象适配器是通过聚合的方式进行适配,这种方式使得Adapter可以对所有的Adaptee类及其子类进行适配而不需要再次定义一个新的类,但是这种方式对源角色的接口进行重写比较困难。

类适配器代码示例

  Target类定义了客户端调用的接口方法

 

public interface Target {
    public void Request();
}

 

  Adaptee定义了目前系统中存在的接口方法SpecialRequest方法,同事Adaptee提供的接口和Target的接口是没有任何关联的

public class Adaptee {
    public void SpecialRequest() {
        System.out.println("Special Request");
    }
}

  Adapter继承了Adaptee类同时实现了Target接口,在此类中本可以重写Adatee类中的SpecialRequest方法,但是此处就不重写了,直接实现了Target类的Request方法,在此方法中调用了SpecialRequest方法并且在调用这个方法的前后可以做目标接口需要的操作,然后将SprecialRequest方法包装成Request方法进行使用。

public class Adapter extends Adaptee implements Target {

    @Override
    public void Request() {
        System.out.println("Ready Adapter Request");
        /*相关操作*/
        SpecialRequest();
        /*相关操作*/
        System.out.println("Adapter Request");
    }
}

  Client调用的代码以及运行结果

public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.Request();
    }
}

运行结果:
Ready Adapter Request
Special Request
Adapter Request

 

对象适配器代码示例

  目标类和源类和类适配器中的代码可一致,需要修改的实现是适配器类中的适配方式:

public interface Target {
    public void Request();
}
public class Adaptee {
    public void SpecialRequest() {
        System.out.println("Special Request");
    }
}

  Adapter类中不再继承Adaptee方法了,仅仅是继承Target方法

public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void Request() {
        System.out.println("Ready Adapter Request");
        /*相关操作*/
        adaptee.SpecialRequest();
        /*相关操作*/
        System.out.println("Adapter Request");
    }
}

  Client调用目标接口

public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.Request();
    }
}

运行结果:
Ready Adapter Request
Special Request
Adapter Request

  使用适配器模式时,可以通过调用自己开发的功能来扩展系统的功能,但是过多的使用适配器模式会导致系统功能十分凌乱,难以读懂,比如通过日志看到系统调用的明明是A接口的功能,结果实际上调用的是B接口等等,所以在使用适配器模式的时候需要注意是否有必要使用,

缺省适配器模式

  缺省适配器模式是适配器模式的一种特例,主要为一个接口提供缺省的实现,这样字类可以通过继承的方式对这个缺省实现进行扩展而不必要通过实现的方式实现接口所提供的所有方法。缺省适配器模式为了适应让一个子类去实现某个接口,但是该子类不需要用到这个接口的所有方法的情况,缺省适配器模式是只对需要的方法进行实现,不需要的方法则不需要实现。

  缺省适配器模式的实现方式如下:

  首先,声明一个客户端调用的接口,并声明该接口的所有方法。

public interface AbstractService {
    public void ServiceOperation1();

    public int ServiceOperation2();

    public String ServiceOperation3();
}

  然后,通过一个ServiceAdapter的抽象类实现AbstractService,并且提供接口方法的所有缺省实现。

public abstract class ServiceAdapter implements AbstractService{
    @Override
    public void ServiceOperation1() {

    }

    @Override
    public int ServiceOperation2() {
        return 0;
    }

    @Override
    public String ServiceOperation3() {
        return null;
    }
}

  最后,抽象方类的子类继承ServiceAdapter的抽象类,并且选择自己所需要的方法给出具体实现。

public class ServiceImpl extends ServiceAdapter {
    @Override
    public void ServiceOperation1() {
        System.out.println("do Operation1");
    }

    @Override
    public int ServiceOperation2() {
        System.out.println("do Operation2");
        return 1;
    }
}

 

posted on 2019-06-10 17:06  会飞的小杰  阅读(158)  评论(0)    收藏  举报

导航