装饰设计模式定义:
使用一种透明的方式来动态的扩展对象的功能。两个类都同时继承或实现一个基类,多功能的对象通过参数获得另一个对象。
使用一个吃饭的案列说明这种设计模式
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();
总结
装饰模式,就是通过参数传递对象,这样就可以调用这个对象已有的功能属性,而不用去继承它,然后再去扩展功能。
网友评论