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


适配器主要用于接口的转换或者将接口不兼容的类对象组合在一起形成对外统一接口,是一种结构性模式,其本质是是一个中间件,适用于类及其对象。
本文希望通过简单的介绍和分析,能让读者对适配器模式有一个简单直观的认识和感知。

1.目的

对现有的类的接口进行转换以符合新的需求。

2.动机

通过转换或者组合,间接复用已有功能模块完成需求。

3.优缺点

优点

提高了类的复用;
组合若干关联对象形成对外提供统一服务的接口;
扩展性、灵活性好。
缺点

过多使用适配模式容易造成代码功能和逻辑意义的混淆。
部分语言对继承的限制,可能至多只能适配一个适配者类,而且目标类必须是抽象类。

4.分类

类适配器
对象适配器
接口适配器
本文主要介绍前两者。

5.主要用途及场景

该模式并不是在设计开发阶段考虑的,主要用在想要修改一个已经存在的接口,或者组合若干关联对象的时候。

想用一个已经存在的类,但其接口不符合需求;
想创建一个可以复用的类,该类可以与其他不相关的类协同工作;
想使用一些已经存在的子类,但是不能对每一个都进行子类化以匹配它们的接口(仅适用于对象Adapter)。对象适配器可以适配他的父类接口。

6.原理

下面是GoF介绍的典型的类适配器模式和对象适配器模式的UML类图

类适配器

原理:通过类继承实现适配,继承Target的接口,继承Adaptee的实现
在这里插入图片描述
对象适配器

原理:通过类对象组合实现适配
在这里插入图片描述
Target:

定义Client真正需要使用的接口。

Adaptee:

其中定义了一个已经存在的接口,也是我们需要进行适配的接口。

Adapter:

对Adaptee和Target的接口进行适配,保证对target中接口的调用可以间接转换为对Adaptee中接口进行调用。

7.实现

接下来先将上面的UML类图转换为两个具体的例子,然后在对每一种类型在使用一个具体例子介绍.
下面我们使用几个例子来实际体验一下代理模式的应用。

7.1 类适配器

定义目标接口类:Target

 public interface Target {
    void request();
}

被适配的类:Adaptee

public class Adaptee {
    public void adapteeRequest() {
        System.out.println("adapteeRequest method of Adaptee! ");
    }
}

适配类Adapter,继承Target的接口request,同时继承Adaptee的实现adapteeRequest

public class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        // TODO Auto-generated method stub
        super.adapteeRequest();
    }
}

演示:

public class Demo {
    public static void main(String [] args) {
        Target target = new Adapter();
        target.request(); // result: adapteeRequest method of Adaptee! 
    }
}

7.2 对象适配器

从上面两张UML图中可以清楚的看出两者的区别,对象中Adapter不在继承Adaptee,而是将Adaptee作为一个数据成员组合到类定义中,从而实现对其接口的访问。

public class Adapter implements Target {
    private Adaptee adaptee = new Adaptee();
    @Override
    public void request() {
        // TODO Auto-generated method stub
        adaptee.adapteeRequest();
    }
}

7.3 类适配器实例——排序

考虑到某系统中有对数据排序的需求,下面使用适配器看一下如何复用现有的排序接口(下面的例子仅仅为了演示,接口不具实际意义);

现有排序类:EffectiveVectorSort

public class EffectVectorSort {
    public void vectorSort() {
        System.out.println("vectorSort method of EffectVectorSort! ");
    }
}

系统排序所需的接口类定义:DataSort

public interface DataSort {
    void sort();
}

定义适配器:SortAdapter

public class SortAdapter extends EffectVectorSort implements DataSort {
    @Override
    public void sort() {
        // TODO Auto-generated method stub
        super.vectorSort();
    }
}

演示:

public class Demo {
    public static void main(String [] args) {
        DataSort dataSort = new SortAdapter();
        dataSort.sort(); // vectorSort method of EffectVectorSort! 
    }
}

7.4对象适配器实例——排序

如果系统中不仅有对向量Vector的排序,也有对元组Tuple和链表LinkList等高级数据结构的排序,那么显然通过无法通过类适配将每一个排序类的子类都继承。这里便可以用到对象适配。

需要修改7.3中的SortAdapter,同时需要定义高级数据结构的排序类。

高级数据结构排序类接口:AdvanceDataSort

public interface AdvanceDataSort {
    void sort();
}

链表排序类:LinkListSort

public class LinkListSort implements AdvanceDataSort {
    @Override
    public void sort() {
        // TODO Auto-generated method stub
        System.out.println("sort method of LinkListSort!");
    }
}

元组排序类:TupleSort

public class TupleSort implements AdvanceDataSort {
    @Override
    public void sort() {
        // TODO Auto-generated method stub
        System.out.println("sort method of TupleSort");
    }
}

重定义适配器:SortAdapter

public class SortAdapter implements DataSort {
    private EffectVectorSort vectorSort = new EffectVectorSort();
    private AdvanceDataSort listSort = new LinkListSort();
    private AdvanceDataSort tupleSort = new TupleSort();
    @Override
    public void sort(String dataType) {
        // TODO Auto-generated method stub
        if(dataType == "vector") {
            vectorSort.vectorSort();
        }
        else if(dataType == "linklist") {
            listSort.sort();
        }
        else if(dataType == "tuple") {
            tupleSort.sort();
        }
        else {
            System.out.println("Invalid Data Type:" + dataType);
        }
    }
}

演示:

public class Demo {
    public static void main(String [] args) {
        DataSort dataSort = new SortAdapter();
        dataSort.sort("vector");      // vectorSort method of EffectVectorSort! 
        dataSort.sort("linklist");    // sort method of LinkListSort!
        dataSort.sort("tuple");       // sort method of TupleSort
        dataSort.sort("dict");        // Invalid Data Type:dict
    }
}

转载

转载声明:
作者:alpha_panda
地址:https://www.cnblogs.com/yssjun/p/11094401.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值