适配者模式详解

出于对设计模式的学习复习,才决定写的这一系列文章,一方面是帮助自己更快的复习记忆,另一方面是帮助有需要的人快速入门,分享自己的学习内容吧。

 

先来张女神图亢奋一下,嘿嘿嘿~(四月是你的谎言)

 

概念和目的

设计模式是众多经验丰富的工程师经过大量的实验花费了很多很多时间才总结出来的,可以说是众多经验的结晶了。在所有的中、大型项目中,设计模式随处可见。使用设计模式,是为了提高代码的可重用性、可读性以及可靠性。适当的使用设计模式可以为日后扩展节省不少工作量,尽可能避免未知bug,提升项目性能。

设计原则

理所当然的,所有的设计模式首先都应该需要遵从的必须是程序开发的六大原则了。如果你对六大原则还不理解,可以看看这篇文章帮你快速了解:最通俗易懂的java 六大原则--代码解析

分类

设计模式有20余种,可分为:

 

适配器模式

 下面将讲解适配器模式,分为:

1、概念解析

2、代码讲解

3、核心思想

4、优缺点

 

概念解析

适配器模式属于结构型模式,就是将某个接口类适配成需要的接口。比如电脑可以读取sd卡信息(因为有一个sd卡插口)现在需要电脑读取tf内存卡卡,但是电脑没有tf内存卡的插口,那就使用一个sd卡读卡器,让tf卡插入读卡器,再把读卡器插入电脑,从而实现电脑读取tf卡。(注意,这里并没有去改变电脑的内部结构吧,电脑仍然以为自己读取的是sk卡)

 代码讲解

首先创建一个电脑的接口和接口实现类,电脑需要能读取sd卡的方法。

/**
 * create time on  2019/5/30
 * function: 电脑的接口类
 */
public interface IComputer {

    //读取sd卡方法
    void readSDk(SDCard sdCard);
}
/**
 * create time on  2019/5/30
 * function: 电脑接口的实现类
 */
public class ComputerImpl implements IComputer {

    /**
     * 读取插入的sd卡信息
     * @param sdCard
     */
    @Override
    public void readSDk(SDCard sdCard) {
        sdCard.readSDCard();
    }
}

现在是创建一个sd卡接口和实现类

/**
 * create time on  2019/5/30
 * function: sd卡接口
 */
public interface SDCard {
     //读sd卡
     void readSDCard();
     //写sd卡
     void writeSDCard();
}
/**
 * create time on  2019/5/30
 * function:  sd卡实现类
 */
public class SDCardImpl implements SDCard {
    private String TAG = "chenhua";
    
    
    @Override
    public void readSDCard() {
        Log.i(TAG,"readSDCard:");
    }

    @Override
    public void writeSDCard() {
        Log.i(TAG, "writeSDCard: ");
    }
}

现在我们在activity中编写如下代码:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //电脑
        ComputerImpl computer = new ComputerImpl();
        //正常读取sdk卡内容
        SDCardImpl sdCard = new SDCardImpl();
        computer.readSDk(sdCard);
    }

在activity中,我们创建一个电脑类,传入一个sd卡类,调用电脑的读取sd方法就可读取sd卡信息了。看log输出

电脑成功读取看sd卡信息。

那现在有新需求了,需要让电脑读取TF卡。首先你能想到的最简单粗暴的思路就是在电脑接口类中增加一个读取TF卡的接口,然后让具体的电脑类去实现。但是这严重违反了开闭原则。对于日后需求的增加,都要增加一个方法,如果之前的电脑类不是你写的,或者内部调用及其复杂,那对于修改原来的电脑类代码工作量无疑巨大,还可能引发bug!这时候可以这么做~

编写一个TF转SD的适配器类,有没有转接口的味道~

/**
 * create time on  2019/5/30
 * function:  sd卡适配器,注意这是一个适配器!实现了SDCard接口
 */
public class SDAdapterTf implements SDCard {

    //插入 TF转SD读取器的  Tf内存卡
    private TFCard tfCard;

    public SDAdapterTf(TFCard tfCard) {
        this.tfCard = tfCard;
    }

    @Override
    public void readSDCard() {
            //sd读卡器内部读取的是tf卡信息。
            tfCard.readTFCard();
    }

    @Override
    public void writeSDCard() {
            //sd卡读卡器内部写入的是tf卡信息
            tfCard.readTFCard();
    }
}

看代码阔以发现,虽然他是SD卡的实现类,但是内部读取的确实TF卡哦~

我们在activity中操作看看

 //通过适配器,创建一个支持TF卡读取的sd卡适配器
        SDAdapterTf sdAdapterTf = new SDAdapterTf(new TFCardImpl());
        //使得电脑出了能读sd卡,还可以读取tf卡,且不改变原来电脑类代码
        computer.readSDk(sdAdapterTf);

看log输出:

确确实实是让电脑读取了TF卡。这就是适配器模式。

 核心思想

继承或者依赖(引用)目标对象,然后实现需要的接口。确保原来代码不改变的情况下,增加新的功能。

分析:比如我们上面的SDAdapterTf类,他就依赖(引用)了我们TFCard对象,然后实现了我们需要转换的SDCard接口。对于SDCard内部的读写方法,我们都重写去调用TFCard的方法,从而达到适配的目的。就是说我们首先写个适配器类,这个类要能拿去插电脑,我们就implement一个能插电脑功能的接口,那我们的目的是把一个不能插电脑的东西通过这个适配器类变成可以查电脑的类,所以我们的适配器内部肯定需要有一个我们打算转换的目标对象,就是代码中的TFCard,通过这个适配器类,我们的TFCard原本不能插电脑,现在可以查电脑了(通过适配器类间接插电脑。)~。

写法思路:

1、我要操作的对象是谁?是TFCard类,

2、我们操作什么?让电脑读取TFCard类。但是电脑只能读取的是SDCard类

3、那就想办法把TFCard接口转为SDCard接口

4、在不改变电脑类内部代码的情况下如何转?写一个实现SDCard的类,那这个实现类一定能被电脑操作,内部获取我要操作的对象TFCard类,重写读写方法,让他读写的是我的目标对象TFCard的内容。

这就是适配者模式的核心思想

优缺点

优点:

1、提高了部分类的复用,比如电脑类就不需要重写修改,即不需要修改旧代码,符合开闭原则。

2、灵活性好,对需要适配的接口写一个适配器类就可以,不用的话直接不适用适配器类就可以,无需要何种删除,何种判断代码。

3、将目标者类(电脑类)与适配者类(TFCard类)解耦,看代码就可以知道了,这两个类从来就没有存在直接的依赖关系

缺点:

1、过多使用系统就会比较乱,可读性很低。明明看到调用的是sd卡的类,可是读出来的却是tfcard。一个项目如果大量使用这种方式,那估计是要哭咯~如果是大量增加新功能,能重构优先选择重构吧。

2、一个适配器类智能适配一个适配者。

 

更多设计模式更新中,请持续关注哦~......

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值