美文网首页Android干货Android开发Android开发经验谈
移动架构师-设计模式篇 《适配器模式》

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

作者: DevCW | 来源:发表于2018-03-15 19:00 被阅读57次

    适配器模式,这个词对于大多数人并不陌生。一说适配器模式, 很多人就想到了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);
                }
            });
    
        }
    

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

    相关文章

      网友评论

        本文标题:移动架构师-设计模式篇 《适配器模式》

        本文链接:https://www.haomeiwen.com/subject/sqodfftx.html