前言
之前已经将五个创建型设计模式介绍完了, 从这一篇开始介绍结构型设计模式, 适配器模式就是结构型模式的一种, 适配器要实现的效果是把 "源" 过渡到 "目标".
适配器模式
在开发过程中, 使用一个已经存在的类, 而他的接口不符合我们的需求. 这个时候我们本着开闭原则, 要创建一个既符合我们需求又实现了已存在的接口的类, 这个类可以把其他不相关或不可预见的类协同起来一起工作. 我们创建的这个类就是适配器类, 起到了一个转换的作用.
适配器模式有类型的适配器模式和对象适配器模式两种实现方式.
面向类的适配器模式
面向类的适配器实现起来并不复杂, 主要的思想就是靠继承来实现适配. 举个, 如果我们在调用一个接口的时候, 发现这个接口中没有能实现我们需求的方法, 然后发现这个接口旁边的一个类中有我们想要的方法, 这个时候我们就可以创建一个适配器类, 来继承接口旁边的这个类, 并实现调用接口. 这样就满足了我们既没有改变调用方式又实现了功能需求.
如下代码功能:
定义一个数据线接口
- public interface IMobilePhone {
- /**
- * 谷歌数据线
- * @return
- */
- String google();
- /**
- * 苹果数据线
- * @return
- */
- String apple();
- }
当我们调用数据线接口时发现没有 type-c 类型接口的数据线, 然后发现了下面的这个类里有.
- public class HuaWei {
- /**
- * 华为的 type-c 数据线
- * @return
- */
- public String huawei(){
- return "huawei:type-C";
- }
- }
然后我们就创建一个适配器类来满足我们的需求.
- public class Adapter extends HuaWei implements IMobilePhone {
- @Override
- public String google() {
- return "Android: 数据线";
- }
- @Override
- public String apple() {
- return "IOS: 数据线";
- }
- }
使用方式如下:
- public class AdapterTest { public static void main(String[] args) {
- HuaWei dataLine = new Adapter();
- String typC = dataLine.huawei();
- System.out.println(typC);
- }
- }
运行结果:
huawei:type-C
在上面的例子中, 我们通过 Adapter 类继承自 HuaWei 类, 然后实现了 IMobilePhone 接口, 做到了适配的效果, 但是这种适配器是有明确规定了父类的. 由于 Java 语言的特性, 类只能单继承, 决定了这个适配器只能用在这个业务当中. 如果我们又需要另一个类里面的方法呢? 这个时候就又需要创建一个子类来实现适配, 这也是为什么这种方式叫类适配器的原因.
面向对象适配器模式
为了解决类适配器只是适配单一类的这个问题, 就又出现了对象适配器模式, 对象适配器, 是将适合类的对象注入到适配器中, 然后达到适配的作用.
其他的代码没有变化, 只需要更改适配器类.
更改后如下所示:
- public class Adapter implements IMobilePhone {
- @Override
- public String google() {
- return "Android: 数据线";
- }
- @Override
- public String apple() {
- return "IOS: 数据线";
- }
- public Adapter(){}
- private HuaWei huaWei;
- public Adapter(HuaWei huaWei){
- this.huaWei = huaWei;
- }
- public String huawei(){
- return huaWei.huawei();
- }
- }
适配器类, 不再继承 HuaWei 类, 而是通过构造函数将 HuaWei 类的对象注入进来, 然后定义一个方法来调用要使用的方法.
测试如下:
- public class AdapterTest {
- public static void main(String[] args) {
- HuaWei huaWei = new HuaWei();
- Adapter dataLine = new Adapter(huaWei);
- String typC = dataLine.huawei();
- System.out.println(typC);
- }
- }
运行结果:
huawei:type-C
对象适配器模式, 可以为多个类进行适配 (多个构造方法), 解决了类适配模式的单一化问题.
但是其实除了对象适配器模式和类适配器模式, 还有一种方式也是实现适配的方法, 接口适配器模式. 当我们想实现一个接口, 但又不想实现所有接口方法, 而只想去实现一部分方法时, 就可以使用接口适配器. 它的做法是在接口和具体实现类中添加一个抽象类, 而用这个抽象类去实现目标接口的所有方法. 而具体的实现类只需要覆盖其需要完成的方法即可.
例如有如下接口:
- public interface MobilePhoneBrand {
- String xiaomi();
- String huawei();
- String apple();
- String vivo();
- String oppo();
- String samsung();
- }
对应的抽象类如下:
- public abstract class MobilePhoneDefault implements MobilePhoneBrand{
- public String xiaomi(){
- return null;
- }
- public String huawei(){
- return null;
- }
- public String apple(){
- return null;
- }
- public String vivo(){
- return null;
- }
- public String oppo(){
- return null;
- }
- public String samsung(){
- return null;
- }
- }
实现类中我只想使用中国品牌的手机, 所以只需实现部分方法就可以了.
- public class ChinaMobilePhone extends MobilePhoneDefault {
- public String xiaomi(){
- return "小米";
- }
- public String huawei(){
- return "华为";
- }
- public String vivo(){
- return "VIVO";
- }
- public String oppo(){
- return "OPPO";
- }
- }
适配器模式的 3 个实现方式介绍完了, 下面来说说适配器模式的结构, 如下图:
适配器模式中有如下 4 个角色:
目标抽象角色 (Target): 定义客户所期待要使用的接口, 在第一个例子中的 IMobilePhone 就是代表的这个角色.
源角色 (Adaptee): 也叫被适配角色, 在第一例子中 HuaWei 代表的就是这个角色.
适配器角色 (Adapter): 用来把源角色转换成符合要求的目标接口设备, 在第一个例子中 Adapter 类代表的就是这个角色.
客户端 (Client): 这个就是具体使用角色, 在第一个例子中的 AdapterTest 代表的就是这个角色.
想了解更多的设计模式请查看 Java 设计模式学习记录 - GoF 设计模式概述.
来源: https://www.cnblogs.com/jimoer/p/9277284.html