Java结构型设计模式-装饰(二)
来源:互联网 发布:非诚勿扰网络直播时间 编辑:程序博客网 时间:2024/06/06 10:35
装饰
意图
动态给一个对象添加额外的职责,就增加功能来说,装饰(Decorator)模式优于继承。装饰属于对象适配器模式的一种。
别名
包装器Wrapper
动机
当我们希望给某个对象而不是整个类添加功能时,例如,一个图形用户界面工具箱允许你对任何一个用户界面组件增加特性,例如为TextView增加边框。
使用继承机制是添加功能的有效途径,子类可以持续拥有边框的特性。但这种方法不够灵活,用户不能控制对组件加框的方式和时机。
一种较为灵活的方式就是将对象嵌入另一个对象中,由这个对象添加边框,我们称这个嵌入的对象为装饰。
适用性
在以下情景可以使用装饰模式
在不影响其他对象的情况下。
当不便于采用生成子类进行扩充的情形,例如父类的子类已经非常多了,从程序设计的角度不便于扩充。
参与者
Component
- 定义一个对象接口,可以给这些对象动态增加职责。
ConcreteComponent
- 定义一个对象,可以给对象增加职责
Decorator
- 抽象装饰者,继承Component接口,从外类来狂战Componet功能
ConcreteDecorator
- 实现抽象装饰着,向ConcreteComponent对象增加职责,一般构造方法接受ConcreteComponent对象。
实现
例如我们的充电器,有些充电器就降压后的5V电压充电,有些充电器带有过流保护的功能。那么我们假设不带过流保护功能的为ConcreteComponent,带过流保护的为ConcreteDecorator。
Component
public interface Component{ public void Voltage5V();}
ConcreteConponent
public class ConcreteComponent implements Component{ @Override public void Voltage5V () { System.out.println("输出5V电压"); }}
Decorator
public abstract class Decorator extends ConcreteComponent{ private ConcreteComponent mConcreteComponent; public Decorator ( ConcreteComponent concreteComponent ) { mConcreteComponent = concreteComponent; } protected abstract void addProtect ();}
ConcreteDecorator
public class ConcreteDecorator extends Decorator{ public ConcreteDecorator ( ConcreteComponent concreteComponent ) { super(concreteComponent); } @Override protected void addProtect () { super.Voltage5V(); System.out.println("增加过流保护\n"); }}
Test
public class Test{ public static void main(String[] args) { ConcreteComponent component = new ConcreteComponent(); ConcreteDecorator decorator = new ConcreteDecorator(component); decorator.addProtect(); //out add protect. component.Voltage5V(); //out not protect. }}
协作
1.得到ConcreteComponet的对象,然后将对象赋入ConcreteDecorator构造器创建对象。
2.ConcreteDecorator对象附加职责。
Android中的Decorator
当我们使用RecyclerView的时候,你可能希望你的RecyclerView有以下功能添加提示无数据的空界面、添加顶部和底部的View、添加下拉监听事件,而因为界面的不同只是需要其中1~3项的功能。这时候装饰模式便派上用场了。下面进行解析。
注:Java类库中的java.io.InputStream、OutputStream、Reader、Writer这些类的所有子类,它们都有一个接受相同类型作为参数的构造函数,返回增加额外方法的子类。
RecyclerView.Adapter相当于Decorator的共同抽象接口。
RecyclerView.Adapter
public static abstract class Adapter<VH extends ViewHolder> { ...... }
EmptyWrapper相当ConcreteDecorator,Decorator的构造器都是同样接受共同抽象接口的实例。
EmptyWrapper
public class EmptyWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ public static final int ITEM_TYPE_EMPTY = Integer.MAX_VALUE - 1; private RecyclerView.Adapter mInnerAdapter; private View mEmptyView; private int mEmptyLayoutId; /** * Receive same abstract class as parameter. * @param adapter RecyclerView.Adapter */ public EmptyWrapper(RecyclerView.Adapter adapter) { mInnerAdapter = adapter; } /** * Add function. */ private boolean isEmpty() { return (mEmptyView != null || mEmptyLayoutId != 0) && mInnerAdapter.getItemCount() == 0; } /** * Add function. * @param emptyView view */ public void setEmptyView(View emptyView) { mEmptyView = emptyView; } /** * Add function. * @param layoutId id */ public void setEmptyView(int layoutId) { mEmptyLayoutId = layoutId; } .....}
同理
HeaderAndFooterWrapper
public class HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ private static final int BASE_ITEM_TYPE_HEADER = 100000; private static final int BASE_ITEM_TYPE_FOOTER = 200000; private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>(); private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>(); private RecyclerView.Adapter mInnerAdapter; public HeaderAndFooterWrapper(RecyclerView.Adapter adapter) { mInnerAdapter = adapter; } /** * add header's View. * @param view */ public void addHeaderView(View view) { mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view); } public void addFootView(View view) { mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view); } .......
Test
private void initRecycleView (){ mAdapter = new CommonAdapter< Scenery.ResultBean >(getActivity(), R.layout.item_scenery, mDatas) { @Override protected void convert ( ViewHolder holder, Scenery.ResultBean info, int position ) { ImageLoader.loadURLImage(getActivity(), info.imgurl, holder.getView(R.id.view_iv_scenery)); holder.setText(R.id.title_tv_scenery, info.title); } }; mEmptyWrapper = new EmptyWrapper< Scenery.ResultBean >(mAdapter); mEmptyWrapper.setEmptyView(LayoutInflater.from(mContext).inflate(R.layout.view_empty, mRecyclerView, false)); mRecyclerView.setAdapter(mEmptyWrapper);}
效果
1.比静态继承更为灵活
与对象的继承相比,Decorator模式提供了更加灵活向对象添加功能的方式,减少了类的复杂程度。
2.避免在层次结构高层的类有太多特征
Decorator模式提供了一种“即用即付”的方式来添加功能,你在设计之前可以不用过多的预见功能,可以使用Decorator逐渐添加功能。遵循了设计的“开闭原则”。
3.不可随意更改Component
因为所有的Decorator都继承了共同的抽象接口Component,如果Component发生变化,会影响所有的Decorator。
4.调试困难
比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐,所以只在必要的时候使用装饰者模式。
5.效率影响
装饰链不能过长,否则会影响效率。
源码下载
0 0
- Java结构型设计模式-装饰(二)
- 设计模式之装饰者模式(二)---java中的装饰者I/O结构
- java设计模式(结构型)之装饰模式
- Java设计模式(7)结构型:装饰模式
- (结构型模式二)装饰模式
- java设计模式之结构型模式-装饰模式
- 设计模式--结构模式--装饰模式--Java
- Decorator装饰设计模式(结构型)
- 设计模式-结构型-装饰
- JAVA设计模式(7) —<结构型>装饰模式(Decorator)
- java设计模式——结构型之装饰模式
- Java设计模式_(结构型)_装饰模式
- java结构型设计模式——装饰模式
- java设计模式——结构型模式专题(一)装饰模式
- Java设计模式概述之结构型模式(装饰器模式)
- Java设计模式之结构型模式-装饰器模式(Decorator)
- (8)设计模式之装饰模式(结构型模式)
- 设计模式 - 结构型模式 - 装饰模式
- 基于C语言Win32API的可视化界面的qaac
- POJ 3311 Hie with the Pie Floyd+状压dp
- Android跑Monkey
- 记录自已学习之宏定义
- 二叉树的路径和
- Java结构型设计模式-装饰(二)
- 手机键盘
- 继承
- MFC多线程学习
- linux 新用户设置
- python2.7无法使用pip(安装easy_install)
- VS2015配置并运行汇编(一步一步照图做)
- Lab3
- 揭秘Spark应用性能调优