设计模式-装饰模式

116 阅读2分钟

装饰设计模式定义:

使用一种透明的方式来动态的扩展对象的功能。两个类都同时继承或实现一个基类,多功能的对象通过参数获得另一个对象。

使用一个吃饭的案列说明这种设计模式

public interface Eat {
  void eat();
}

public class PersionEat implements Eat {
  @Override
  public void eat() {
      Log.e("TAG", "人吃饭吃菜");
  }
}
  • 两个类通过装饰模式,扩展已有的功能

public class StudentEat implements Eat {

private Eat mEat;

//通过参数对象,获得已有的功能
public StudentEat(PersionEat eat) {
    this.mEat = eat;
}

@Override
public void eat() {
    Log.e("TAG", "点个菜");
    mEat.eat(); //共有功能
    Log.d("TAG", "盘子送回指定的地点");
}

}

public class TeacherEat implements Eat {

private Eat mEat;

//通过参数对象,获得已有的功能
public TeacherEat(PersionEat eat) {
    this.mEat = eat;
}
@Override
public void eat() {
    Log.e("TAG", "喝个汤");
    Log.e("TAG", "点个菜");
    mEat.eat();//共有功能
    Log.d("TAG","盘子不用送,吃完走人");
}

}

这就是装饰模式的简单案列,**就是通过构造参数拿到共有功能的对象,然后在此对象的基础添加功能。**

#### 源码中装饰模式的案列
**1.参考listView的recyclerView扩展可以添加首尾的Adapter**,在原本的Adapter的基本上,扩展可以添加首尾的Adapter。

public class HeaderAndFooterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private static final int BASE_ITEM_TYPE_HEADER = 2048;
private static final int BASE_ITEM_TYPE_FOOTER = 4096;

private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat<View> mFooterViews = new SparseArrayCompat<>();

private RecyclerView.Adapter mAdapter;

//拿到原有的adapter
public HeaderAndFooterAdapter(@NonNull RecyclerView.Adapter adapter) {
    mAdapter = adapter;
}

//实现原有的adapter的onCreateVH功能,并增加首尾的onCreateVH功能
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (mHeaderViews.get(viewType) != null) {
        return new RecyclerView.ViewHolder(mHeaderViews.get(viewType)) {
        };
    } else if (mFooterViews.get(viewType) != null) {
        return new RecyclerView.ViewHolder(mFooterViews.get(viewType)) {
        };
    } else {
        return mAdapter.onCreateViewHolder(parent, viewType);
    }

}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    //如果是header 或 footer就不绑定数据
    if (isHeaderViewOrFooterView(position)) {
        return;
    }
    //通过对象,实现原有的功能
    mAdapter.onBindViewHolder(holder, mAdapter.getItemViewType(getRealItemPosition(position)));
}

@Override
public int getItemViewType(int position) {
    if (isHeaderView(position)) {
        return mHeaderViews.keyAt(position);
    } else if (isFooterView(position)) {
        return mFooterViews.keyAt(position - getHeadersCount() - getRealItemCount());
    } else {
        return mAdapter.getItemViewType(getRealItemPosition(position));
    }
}

@Override
public int getItemCount() {
    return getHeadersCount() + getFootersCount() + getRealItemCount();
}

public void addHeaderView(View view) { mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view); }

public void addFooterView(View view) {
    mFooterViews.put(mFooterViews.size() + BASE_ITEM_TYPE_FOOTER, view);
}

**2.ContextWrapper**

public class ContextWrapper extends Context { @UnsupportedAppUsage Context mBase;

public ContextWrapper(Context base) {
    mBase = base;
}
...

}


**3.io**

FileReader fr = new FileReader("sss.txt"); //把FileReader 对象传进去,扩展功能,比如扩展可以一行一行阅读 BufferedReader br = new BufferedReader(fr); br.readLine();

### 总结
装饰模式,就是通过参数传递对象,这样就可以调用这个对象已有的功能属性,而不用去继承它,然后再去扩展功能。