移动架构师-设计模式篇 《适配器模式》

适配器模式,这个词对于大多数人并不陌生。一说适配器模式, 很多人就想到了ListView啊, Adapter, 对,ListView与Adapter确实是适配器模式在Android中最经典的使用之一了。也有一些人可能不太清楚,会说我没用过啊,其实这个还真不一定。那么请不清楚适配器模式的小伙伴们跟随我的脚步去探索,希望到最后你能说,哦,原来是这样;对,就是这样的。


1. 官方解释

适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为
接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

2.概念理解

适配器模式解决什么问题呢 ? 或许很多人不明白,或者说知道一些,但是不甚清楚。先说一下我的理解吧。

适配器模式解决的是兼容冲突问题。通俗讲就是,我想要一个东西,但是目前手上没有,只有一个类似的。这
就是兼容冲突,我想要的,没有,只有一个不满足我条件的。

举个例子, 我现在手上有一个笔记本,系统是Windows的; 那么我现在想用这个笔记本来开发NDK,大家都
知道,C库的编译或ndk的开发是以Linux系统为佳的,那么我怎么办呢 ?答案当然是重装系统!

对重装系统来进行分析, 我现在有一个Windows系统的笔记本,但需要的是一个Linux系统的,此时需求便不兼容了,也就是冲突了。因此要重装系统。

适配器解决的问题就是重装系统, 如何把当前提供的不满足要求的资源,转化为当前需要的资源,就是这么简单~

相信对于适配器模式的概念都理解了,它的作用就在于适配,也可以称为转化。比如我们服务端返回的Json字符串,但是我们需要实体类。如果我们想要统一处理,比如如下伪代码

public class Response {    // 服务端返回的封装类
      String json; // 服务端返回的是json数据
}

public interface Responsable<T> {
      public T getResponseBean(Class<T> cls); // 我们想要返回的是实体类, 参数为什么实体类
}

public class BeanResponse<T> extends Response implements Responsable<T> {
        
        T getResponseBean(Class<T> cls) {
               // 取出cls的变量
              // 与json的字段对比,如果一致就赋值
              // 得到一个对象并返回
         }
}

以上这段代码就很好的契合了适配器的定义,把不满足要求的对象,转化为我们需要的对象。明白了什么是适配器模式,怎么用,现在来说下理论。


适配器模式分为3种, 分别为类适配, 对象适配, 接口适配

类适配模式

上述代码, 以继承原始类,实现目标接口实现适配的方式,称之为类适配模式

类适配模式的核心是以继承的方式来实现,也就是我们手上不满足当前要求的Windows笔记本,返回的JSON格式的数据,通过继承的方式取到。以下以一段简短的代码来说明

/**
 * @author qichunjie 2018/3/14
 */

public class ClassAdapter {
    
    public void main(String[] args) {
        UserAdapter adapter = new UserAdapter();
        adapter.getDescription();
    }

    public class User {
        private String name = "小明";
        private int age = 18;

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }

    public interface Descriptor {
        String getDescription();
    }

    public  class UserAdapter extends User implements Descriptor {

        @Override
        public String getDescription() {
            return getName() + "今年" + getAge() + "岁了。";
        }
    }

}

对象适配模式

如果明白了类适配,那么对象适配就再容易不过了,我跟你解释一句,保证你在不知道什么是对象适配的情况下写出来。那么关键的地方来了,我想解释什么呢?

我们已经知道,类适配是通过继承的形式来得到当前不满足条件的对象,也就是Windows系统的笔记本。对象适配则是通过传参的形式来得到当前不满足条件的对象。

以类适配的代码为例,我们想得到一个完整的描述,但是目前只有Name和Age。

类适配 : 继承User得到Name和Age
对象适配: 传入User对象,来得到Name和Age

对象适配模式的代码如下:

public class ClassAdapter {

    public void main(String[] args) {
        UserAdapter adapter = new UserAdapter();
        adapter.getDescription();
    }

    public class User {
        private String name = "小明";
        private int age = 18;

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }

    public interface Descriptor {
        String getDescription();
    }

    public class UserAdapter implements Descriptor {

        private User user;

        public UserAdapter(User user) {
            this.user = user;
        }

        @Override
        public String getDescription() {
            return user.getName() + "今年" + user.getAge() + "岁了。";
        }
    }

}

不再继承,直接传入已知不满足条件的对象,就是这么简单。


接口适配模式

类与对象适配的区别在于类信息的来源不同,一个是继承, 一个是传参。 接口适配模式中,这个不满足条件的已知对象,不是一个类了,而是接口。

相信很多人都用过动画, 很多时候我们需要在动画结束的时候执行一些逻辑,比如启动页面动画完毕之后跳转到主页面啊, 比如动画A完了之后,控件B要显示出来等。我们往往做的一件事肯定就是监听动画的执行,
如下:

Animator animator = ...; // 此处实例一个对象
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                
            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

宝宝觉得很委屈啊, 明明只需要一个onAnimationEnd(), 现在却不得不实现其他的3个方法,得不偿失啊有木有。对我这种对冗余厌烦到骨子里的人,真真是受不了的。

针对这种情况,我们常做的一个方法就是来一个类AnimatorImpl实现这个接口,方法体保持为空。为什么呢?因为无论是接口,还是抽象类的抽象方法,都是必须要实现所有方法的。 但是一个普通类就不用了,我们不实现这些方法, 在使用的时候,需要哪个方法,重写哪个方法即可。我相信有人这么用过,或许他还不明白,这就是接口适配器模式...

接口适配器:通过实现已知的不满足条件的接口, 来确保只得到我们需要的方法。

我们拥有的对象: 一个包含N个方法的接口, N > 1

我们需要的对象: N个方法中的一个或几个 , 少于N个

我们需要如何做: 通过类实现接口, 想重写几个几个方法,就重写几个方法

代码如下:

public class AnimatorImpl implements Animator.AnimatorListener {

        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {

        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    }

    public void main(String[] args) {
        Animator animator = null;
        animator.addListener(new AnimatorImpl(){

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });

    }

怎么样,是不是很简单呢 ? 应用场景也很好理解。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容