标签:override over final uml dap MF 兼容 ide 装饰者
装饰模式也叫做包装模式,是结构型设计模式之一。目的是为了给一个类或对象增加行为。可以是继承的一种替代。
装饰模式也很好理解,比如一个人,给他装上火箭就能上天了,装上潜水服就能下海了,但本身还是个人,人没有任何变化。
在不使用的继承的方式下,采用装饰设计模式可以扩展一个对象的功能,可以使一个对象变得越来越强大。
动态地给一个对象添加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。
角色职责
抽象组件类:
public abstract class Component {
public abstract void operate();
}
组件的一个具体实现类,也就是被装饰者者:
public class ConcreteComponent extends Component {
@Override
public void operate() {
System.out.println("被装饰者的操作");
}
}
抽象的装饰者,持有一个被装饰者的引用:
public abstract class Decorator extends Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operate() {
component.operate();
}
}
具体的两个装饰者,拓展功能:
ConcreteDecoratorA:
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operate() {
operateA();
super.operate();
operateB();
}
private void operateA(){
System.out.println("装饰者A在被装饰者的操作之前加些操作");
}
private void operateB(){
System.out.println("装饰者A在被装饰者的操作之前后加些操作");
}
}
ConcreteDecoratorB:
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operate() {
operateA();
super.operate();
operateB();
}
private void operateA(){
System.out.println("装饰者B在被装饰者的操作之前加些操作");
}
private void operateB(){
System.out.println("装饰者B在被装饰者的操作之前后加些操作");
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(component);
ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(component);
concreteDecoratorA.operate();
concreteDecoratorB.operate();
}
}
输出:
装饰类并没有在原来的类上做审核改动,只是拓展了一些操作。通过不同的包装类就能拓展不同的功能。而传入不同的被包装类,也能拓展不同的具体对象。
我们知道RecyclerView是不支持添加addHeaderView和addFooterView功能的,但是我们在项目开发中经常还要使用到这两个功能。怎么办呢?最好的办法就是在不破坏原理结构的继承上扩展出这两个功能,所以首先考虑装模式来实现这个功能。
在实现逻辑之前先画uml图来缕清其中的关系
其中MyRecyclerViewAdapter是我们实际上处理逻辑的adapter,需要添加头部和底部功能时,将其传入的WrapRecyclerAdapter中,使用WrapRecyclerAdapter添加头部和底部即可。
WrapRecyclerAdapter
/**
* Created by hcDarren on 2017/9/30.
* 装饰设计模式的 RecyclerView.Adapter,我们对其进行功能扩展,使它支持头部和底部的添加
*/
public class WrapRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
// 原来的RecyclerView.Adapter,并不支持头部和底部的添加
private final RecyclerView.Adapter mRealAdapter;
ArrayList<View> mHeaderViews;
ArrayList<View> mFooterViews;
/**
*传入被装饰者
*/
public WrapRecyclerAdapter(RecyclerView.Adapter realAdapter){
this.mRealAdapter = realAdapter;
mRealAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
notifyDataSetChanged();
}
});
mHeaderViews = new ArrayList<>();
mFooterViews = new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
// 问题如果想知道是哪个部分,必须要知道 position 也就是位置 ,但是目前只有 viewType
// 头部返回 头部的ViewHolder
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return createHeaderFooterViewHolder(mHeaderViews.get(position));
}
// mRealAdapter 返回 mRealAdapter的ViewHolder
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mRealAdapter != null) {
adapterCount = mRealAdapter.getItemCount();
if (adjPosition < adapterCount) {
// 直接传 position ,不兼容 万能适配多布局条目
return mRealAdapter.onCreateViewHolder(parent,mRealAdapter.getItemViewType(adjPosition));
}
}
// 底部返回 底部的ViewHolder
// Footer (off-limits positions will throw an IndexOutOfBoundsException)
return createHeaderFooterViewHolder(mFooterViews.get(adjPosition - adapterCount));
}
private RecyclerView.ViewHolder createHeaderFooterViewHolder(View view){
return new RecyclerView.ViewHolder(view){};
}
public int getHeadersCount() {
return mHeaderViews.size();
}
public int getFootersCount() {
return mFooterViews.size();
}
@Override
public int getItemViewType(int position) {
// 把位置作为 viewType
return position;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// 这个方法先不写,测试一下
// 头部和底部是都不需要做处理的,只要 mRealAdapter 要去做处理
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return ;
}
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mRealAdapter != null) {
adapterCount = mRealAdapter.getItemCount();
if (adjPosition < adapterCount) {
mRealAdapter.onBindViewHolder(holder,position);
}
}
}
@Override
public int getItemCount() { // 总共返回多少条 = 底部条数+头部条数+真实的Adapter条数
return mFooterViews.size()+mHeaderViews.size()+mRealAdapter.getItemCount();
}
/**
* 添加头部
*/
public void addHeaderView(View view){
if(!mHeaderViews.contains(view)){
mHeaderViews.add(view);
notifyDataSetChanged();
}
}
/**
* 添加底部
*/
public void addFooterView(View view){
if(!mFooterViews.contains(view)){
mFooterViews.add(view);
notifyDataSetChanged();
}
}
/**
* 移除头部
*/
public void removeHeaderView(View view){
if(mHeaderViews.contains(view)){
mHeaderViews.remove(view);
notifyDataSetChanged();
}
}
/**
* 移除底部
* @param view
*/
public void removeFooterView(View view){
if(mFooterViews.contains(view)){
mFooterViews.remove(view);
notifyDataSetChanged();
}
}
}
标签:override over final uml dap MF 兼容 ide 装饰者
原文地址:https://www.cnblogs.com/gxl1995/p/9063166.html