换个角度看看我们最熟悉的陌生人:适配器模式

720 阅读3分钟

     说起适配器模式,相信很多同学都对适配器模式有所了解,说到ListView、RecyclerView都是使用了适配器模式,这是从使用的方面来说的,如果从理论的角度来阐述一下,什么是适配器模式,在什么场景下使用适配器模式,可能很多的同学就不清楚了。 

      我们学习理论呢,更多的是想将实际应用进行一个抽象,这样做的目的呢?就是在一些合适的场景下,我们更能够去选择合适的模式来帮助我们解决问题。 

       现在就让我们从理论结合实际来学习一下吧。 

适配器模式的使用场景

1、用户使用现有的类的接口无法满足需求,这个时候,我们需要给用户暴漏一个新的接口,此时可以用到适配器模式。 

比如:比如有一个类PersonManager,提供了一个persons()接口,内部输出了所有人的信息。 但是用户需要一个统计所有人个数的接口,而我们我无法去修改PersonManager,只能在此基础上封装一个类PersonMangerAdapter,那么这个时候,我们就可以给用户需要提供它需要的接口。

2、需要一个统一的输出接口,但是输入类型是不可知的。 

比如:ListView的Adapter,通过getView方法返回的Item View都是一个View,是一个统一的输出接口,但是用户输入,也就是构造的类型千变万化,ListView这个哥么只需要知道Adapter的getView方法返回的是一个View就好,具体是什么样的View我不关心。 Andorid架构师将这些变化的部分交给用户来处理,通过getCount,getItemt等几个方法来应对变化,灵活的应用了适配器模式,达到了无限适配,拥抱变化的目的。 类似于:富士康工厂和人力中心一样。 

上面的学习,相信给你不一样的视角吧。

下面我们继续学习适配器模式的分类,很多同学应该都不清楚,那么我们学习一下。

适配器模式的分类

类适配器模式。 

对象适配器模式。 

那么他们之间有什么区别呢?

类适配器模式(父子关系:需要继承)

类适配器模式的UML类图如下:

具体实现步骤如下:

第一步:定义一个接口Target。

package com.example.createproject;

public interface Target {

    void operation1();

    void operation2();
}

第二步:定义一个对于用户来说API不符合的类。

package com.example.createproject;

import android.util.Log;

public class Adaptee {

    private static final String TAG = Adaptee.class.getSimpleName();

    public void operation3(){
        Log.e(TAG,"operation3执行");
    }
}

第三步:定义适配器类,需要继承API不符合的类,同时实现需要扩展的方法。

package com.example.createproject;

import android.util.Log;

public class Adapter extends Adaptee implements Target{

    private static final String TAG = Adapter.class.getSimpleName();

    @Override
    public void operation1() {

    }

    @Override
    public void operation2() {
        operation3();
        Log.e(TAG,"加工");
    }
}

第四步:我们看看用户调用的效果怎么样。

package com.example.createproject

import android.support.v7.app.AppCompatActivity
import android.os.Bundle

class Test8Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main4)

        // 用户通过Adaptee 没有办法调用operation2()方法
        // 那么可以构造一个Adapter类来实现
        val adapter = Adapter()
        adapter.operation2()

    }
}

下面我们来继续学习一下对象适配器模式

对象适配器模式(兄弟关系:需要代理)

UML类图如下:

具体实现如下:

第一步:定义一个接口。

package com.example.createproject;

public interface Target {

    void operation1();

    void operation2();
}

第二步:定义一个对于用户来说API不符合的类。

package com.example.createproject;

import android.util.Log;

public class Adaptee {

    private static final String TAG = Adaptee.class.getSimpleName();

    public void operation3(){
        Log.e(TAG,"operation3执行");
    }
}

第三步:定义对象适配器。

package com.example.createproject;

import android.util.Log;

public class Adapter implements Target{

    Adaptee adaptee;

    private static final String TAG = Adapter.class.getSimpleName();

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void operation1() {

    }

    @Override
    public void operation2() {
        adaptee.operation3();
        Log.e(TAG,"加工");
    }
}

第四步:看下如何调用的

package com.example.createproject

import android.support.v7.app.AppCompatActivity
import android.os.Bundle

class Test8Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main4)

        // 用户通过Adaptee 没有办法调用operation2()方法
        // 那么可以构造一个Adapter类来实现
        val adaptee = Adaptee()
        val adapter = Adapter(adaptee)
        adapter.operation2()

    }
}

通过上面的例子,我们来总结一下他们之间的区别

类适配器模式VS对象适配器