Java设计模式之适配器模式

概述

适配器模式是结构型设计模式之一,其在不修改原来两个模块代码的情况下,将两个不兼容的类融合在一起,有点像粘合剂,通过转换使得他们能够协作起来,
符合了开闭原则.

关于适配器模式扩展阅读: 适配器模式原理及实例介绍

定义

适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配无法在一起工作的两个类可以在一起工作.

使用场景

  • 系统需要使用现有的类,而此类接口不符合系统的需要,即接口不兼容
  • 想要建立一个可重复使用的类,用于关联彼此没有太大关联的一些类(包括即将引入的类)
  • 需要一个统一的输出接口,而输入端类型不确定.

UML

Adapter模式的结构图如下.

Java设计模式之适配器模式_第1张图片

  • Target:目标角色,期待得到的接口.
  • Adaptee:适配者角色,被适配的接口.
  • Adapter:适配器角色,将源接口转换成目标接口.

分类

适配器模式分为类适配器模式和对象适配器模式,类适配器通过继承,是静态的定义方式.
而对象适配器通过代理,是动态组合的方式。

示例代码如下:

//Target角色
public interface FiveVolt {
    public int getVolt5();
}

//Adaptee角色
public class Volt220 {
    public int getVolt220(){
        return 220;
    }
}

类适配器

//Adapter角色
public class VoltAdapter extends Volt220 implements FiveVolt{
    @Override
    public int getVolt5() {
        return 5;
    }
}

对象适配器

//Adapter 角色
public class VoltAdapter implements FiveVolt{
    Volt220 volt220;

    public VoltAdapter(Volt220 volt220) {
        this.volt220 = volt220;
    }

    @Override public int getVolt5() {
        return 5;
    }

    public int getVolt220(){
        return volt220.getVolt220();
    }
}

对象适配器比类适配器更加灵活,被适配对象中的方法不会被暴露出来,在使用中应尽量使用对象适配器,多用合成或聚合,少用继承.

应用实例

根据Adapter的规则和使用场景,我们来模拟一个最简单的向LinearLayout中添加数据的操作,
首先在这个操作中,我们不知道输入源,但是我们知道 加入到LinearLayout中的数据都是View

效果图如下:
Java设计模式之适配器模式_第2张图片

一 . 首先定义Adapter,这里就省略了接口的定义了,和Android中的BaseAdapter类似

public abstract class ItemAdapter<T> {

  //绑定View的数据源
  private List mDatas;

  public ItemAdapter(List datas) {
    if (datas == null) datas = new ArrayList<>(0);
    mDatas = datas;
  }

  public ItemAdapter(T[] datas) {
    mDatas = new ArrayList<>(Arrays.asList(datas));
  }

  // 需要用户来定义的 view ,
  protected abstract View getView(ViewGroup parent, int position, T t);

  // 获取每个Item
  protected T getItem(int position) {
    return mDatas.get(position);
  }

  // 获取数据源的大小
  protected int getCount() {
    return mDatas.size();
  }

  // 注册数据源变化的监听器
  public void registerDataSetObserver(DataSetObserver observer) {
    mDataSetObservable.registerObserver(observer);
  }

  // 移除监听器
  public void unregisterDataSetObserver(DataSetObserver observer) {
    mDataSetObservable.unregisterObserver(observer);
  }

  private final DataSetObservable mDataSetObservable = new DataSetObservable();

  // 通知数据源 更新
  public void notifyDataSetChanged() {
    mDataSetObservable.notifyChanged();
  }
}

二 . 接下来就可以通过Adapter来获取数据了

public class Linear extends LinearLayout {
  private ItemAdapter mItemAdapter;

  private DataSetObserver mDataSetObserver = new DataSetObserver() {
    @Override public void onChanged() {
      super.onChanged();
      onChange();
    }

    @Override public void onInvalidated() {
      super.onInvalidated();
    }
  };

  private void onChange() {

    if (null == mItemAdapter) return;
    int count = mItemAdapter.getCount();

    for (int i = 0; i < count; ++i) {

      View view = mItemAdapter.getView(this, i, mItemAdapter.getItem(i));

      addView(view);
    }
  }

  public void setAdapter(ItemAdapter itemAdapter) {
    if (mItemAdapter != null && mDataSetObserver != null) {
      mItemAdapter.unregisterDataSetObserver(mDataSetObserver);
    }
    this.mItemAdapter = itemAdapter;
    if (null != mItemAdapter) {
      mItemAdapter.registerDataSetObserver(mDataSetObserver);
      mItemAdapter.notifyDataSetChanged();
    }
  }
  //....
}

更多关于Adapter介绍:
适配器模式原理及实例介绍

java/android 设计模式学习笔记(6):适配器模式

《JAVA与模式》之适配器模式

实例代码

DesignPatterns

你可能感兴趣的:(设计模式,Java基础,Java设计模式)