Android中适配器模式

设计模式系列:
        0. Android开发常用设计模式;

        1. Android中单例模式;

        2. Android中建造者(builder)模式;

        3. Android中观察者模式;

        4. Android中原型模式;

        5. Android中策略模式;

        6. Android中工厂模式;

        7. Android中代理模式;

        8. Android中装饰者模式;

        9. Android中适配器模式;


  三毛:”我的白,你用过第三方图片加载库Glide嘛”

  小白:嗯嗯,平常大概就像下面那样使用

 Glide.with(this)
      .load("url")
      .error(R.mipmap.error)
      .diskCacheStrategy(DiskCacheStrategy.SOURCE)
      .into(imageView);


一、常见需求场景

  三毛:”如果要你Glide加载的图片是圆形或圆角图片,你认为要怎么整捏(不考虑自定义的ImageView)”


二、基本解决方法

  小白:如果没方法设置的话,我想直接改源码,也就是在源码那里,添加多个方法,当设置图片的时候,给客户端选择要正常图片还是圆形或圆角图片


三、基本解决方法存在的问题

  三毛:”可是你没有把Glide项目拉下来作为module,也就是你根本没有源码,炸么改?就算你本地有源码,你为了个图片类型就修改源码,违反设计模式的开闭原则不说,万一到时候因为改源码出了bug…”

  小白:那要怎么做好捏Android中适配器模式_第1张图片


四、适配器模式写法

适配器模式定义:把一个类的接口换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。


  三毛:”对于这种原本接口无法完全满足当前的需求时,可以使用适配器模式。下面是大话设计模式的一段话”

从功能上讲这些接口不兼容的类一般具有相同或相似的功能。通常我们通过修改该类的接口来解决这种接口不兼容的情形,但是如果我们不愿意为了某个功能或应用而去修改原有的接口,或我们压根就没有原有对象的源码怎么办呢


  三毛:”其实Glide在设计的时候人家也是考虑到了,虽然不是直接设置类型,但是提供了一个方法transform(),方法里的参数要传BitmapTransformation类实例,然后你想怎么自定义就怎么自定义”

  小白:奥,之前没用过,不知道


  三毛:”下面我们写个转换类(其实就是适配器模式),把图片转换成我们想要的形状”

//继承Glide提供的抽象类BitmapTransformation
public class CircleAdapter extends BitmapTransformation {

    public CircleAdapter(Context context) {
        super(context);
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        //在这里把图片转换成你需要的形状...
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName();
    }
}

//使用
  Glide.with(this)
      .load("url")
      .error(R.mipmap.error)
      .diskCacheStrategy(DiskCacheStrategy.SOURCE)
      .transform(new CircleAdapter(this))//利用Glide提供给的方法使用我们写好的转换器
      .into(imageView);



适配器模式解释:

  小白: Android中适配器模式_第2张图片 这不是继承重写嘛,难道继承重写就是适配器模式?


  三毛:”继承重写当然不是适配器模式”

  小白: 这里写图片描述那你为嘛还说上面就是适配器模式

  三毛:”我现在举个适配器模式标准例子”

//接口IA
public interface IA {
    void A();
}

//类A
public class A implements IA{
    @Override
    public void A() {
        init();
        //下一步操作...
    }

    public void init(){
        //初始化操作...
    }
}


//------------------------分割线------------------------//


//接口IB
public interface IB {
    void B();
}

//现在要写个CircleAdapterB类,要实现接口IB
public class CircleAdapterB  implements IB{
    @Override
    public void B() {
        //在这里做操作前,也要初始化,发现上面的类B已经写好的初始化方法,
        //也和这里要写的初始化方法一样
    }
}

//那么只要继承类A就好了
public class CircleAdapterB extends A implements IB {
    @Override
    public void B() {
        init();
        //下一步操作...
    }
}



  小白:上面IA,IB接口不同,但是CircleAdapterB类使它们能够在一起工作,这就是适配器模式,原来牙齿

  三毛:”既然你明白了上面的小例子,对于前面的CircleAdapter类也是一个意思,继承某接口(只不过它是抽象类)重写transform方法,然后调用了某类的方法(这里调用父类构造函数进行初始化)”

  小白:Android中适配器模式_第3张图片 感觉怪怪的,但是又说不上来…


  三毛:“那是因为BitmapTransformation是抽象类,而小例子A不是抽象类,其实没多大区别,你不能因为别人换了个包装,你就不认识它,说它不是适配器模式了啊,这也说明你对抽象类还是不能很好的理解使用呦,我的白”

  三毛:”除了这个,像ListView的自定义适配器(继承BaseAdapter)、基类…都使用了适配器模式喔”

  小白:Android中适配器模式_第4张图片


  三毛:“适配器模式一般分为两种写法,但是不管有多少种写法,它的本质’原本因接口不匹配而无法在一起工作的两个类能够在一起工作’是不会变的,下面我举几个简单小例子给你看看两种写法方式”

适配器模式一般分为两种写法:(1)类适配器模式;

              (2)对象适配器模式。



(1)类适配器模式

原理:通过继承来实现适配器功能。

//接口IA
public interface IA {
    void A();
}

//类A
public class A implements IA{
    @Override
    public void A() {
        init();
        //下一步操作...
    }

    public void init(){
        //初始化操作...
    }
}


//------------------------分割线------------------------//


//接口IB
public interface IB {
    void B();
}

//现在要写个CircleAdapterB类,要实现接口IB
public class CircleAdapterB  implements IB{
    @Override
    public void B() {
        //在这里做操作前,也要初始化,发现上面的类B已经写好的初始化方法,
        //也和这里要写的初始化方法一样
    }
}

//那么只要继承类A就好了
public class CircleAdapterB extends A implements IB {
    @Override
    public void B() {
        init();
        //下一步操作...
    }
}



(2)对象适配器模式

 原理:通过组合来实现适配器功能。

//接口IA
public interface IA {
    void A();
}

//类A
public class A implements IA{
    @Override
    public void A() {
        init();
        //下一步操作...
    }

    public void init(){
        //初始化操作...
    }
}


//------------------------分割线------------------------//


//接口IB
public interface IB {
    void B();
}

//现在要写个CircleAdapterB类,要实现接口IB
public class CircleAdapterB  implements IB{
    @Override
    public void B() {
        //在这里做操作前,也要初始化,发现上面的类B已经写好的初始化方法,
        //也和这里要写的初始化方法一样
    }
}

//不使用继承,使用对象
public class CircleAdapterB implements IB {
    private A mA;

    public CircleAdapterB(A a) {
        this.mA = a;
    }

    @Override
    public void B() {
        mA.init();
        //下一步操作...
    }
}


五、适配器模式和普通写法区别


1、复用性好;

2、灵活性和扩展性好,符合开闭原则;

你可能感兴趣的:(开发常用的设计模式)