装饰设计模式
又称包装设计模式,用来动态的扩展对象的功能,也是继承关系的一种替代方案之一。
怎么写:一般都是把类对象作为构造函数传递。
使用场景:需要透明且动态的扩展类的功能时。
UML
角色介绍
- Component:抽象组件,可以是一个接口或抽象类,充当的就是被装饰的原始对象。
- ConcreteComponent:组件具体实现类,是我们装饰的具体对象
- Decorator:抽象装饰者,职责就是为了装饰我们的组件对象,内部一定要有一个窒息那个组建对象的引用。
- ConcreteDecoratorA:装饰者的具体实现,对抽象装饰者的具体实现。
抽象组件1
2
3
4
5
6
7
8
9/**
* @Author sunxin
* @Date 2018/4/1 11:43
* @Description 抽象组件,可以是一个接口或抽象类,充当的就是被装饰的原始对象
*/
public abstract class Component {
public abstract void operate();
}
组件具体实现类1
2
3
4
5
6
7
8
9
10
11
12/**
* @Author sunxin
* @Date 2018/4/1 11:45
* @Description 组件具体实现类,是我们装饰的具体对象
*/
public class ConcreteComponent extends Component {
public void operate() {
}
}
抽象装饰者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* @Author sunxin
* @Date 2018/4/1 11:51
* @Description 抽象装饰者
*/
public abstract class Decorator extends Component {
/**
* 持有一个Component对象的引用
*/
private Component mComponent;
/**
* 构造一个持有该对象的构造函数
* @param component
*/
public Decorator(Component component) {
mComponent = component;
}
public void operate() {
mComponent.operate();
}
}
装饰者具体实现类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38/**
* @Author sunxin
* @Date 2018/4/1 11:55
* @Description 装饰者具体实现类
*/
public class ConcreteDecoratorA extends Decorator {
/**
* 构造一个持有该对象的构造函数
*
* @param component
*/
public ConcreteDecoratorA(Component component) {
super(component);
}
public void operate() {
//装饰方法可以在父类方法之前调用也可在之后调用
operateA();
super.operate();
operateB();
}
/**
* 自定义装饰A方法
*/
public void operateA() {
}
/**
* 自定义装饰A方法
*/
public void operateB() {
}
}
最后调用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* @Author sunxin
* @Date 2018/4/1 11:56
* @Description 最后调用
*/
public class Client {
public void main(String args[]){
//构造被装饰的组件对象
Component component = new ConcreteComponent();
//根据组件对象构造装饰者对象A并调用,此时相当于给组件对象增加装饰者A的功能方法
Decorator decorator = new ConcreteDecoratorA(component);
decorator.operate();
}
}
实例:使用装饰设计模式为RecyclerView添加头布局和脚布局
模仿ListView,可以直接调用RecyclerView.addHeaderView 方法。主要是装饰RecyclerView.Adapter
1.自定义WrapRecyclerViewAdapter 继承自RecyclerView.Adapter
1 | /** |
2.重写RecyclerView,为其增加添加头布局和脚布局的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72/**
* @Author sunxin
* @Date 2018/4/12 0012 上午 11:21
* @Description 重写RecyclerView,添加增强方法
*/
public class WrapRecyclerView extends RecyclerView {
private WrapRecyclerAdapter mRecyclerAdapter;
public WrapRecyclerView(Context context) {
super(context);
}
public WrapRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public WrapRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setAdapter(Adapter adapter) {
// 在这里装饰原来的 Adapter,为其增加添加头脚的布局
mRecyclerAdapter = new WrapRecyclerAdapter(adapter);
super.setAdapter(mRecyclerAdapter);
}
/**
* 添加头布局
*
* @param view
*/
public void addHeaderView(View view) {
if (mRecyclerAdapter != null) {
mRecyclerAdapter.addHeaderView(view);
}
}
/**
* 添加底部局
*
* @param view
*/
public void addFooterView(View view) {
if (mRecyclerAdapter != null) {
mRecyclerAdapter.addFooterView(view);
}
}
/**
* 移除
*
* @param view
*/
public void removeHeaderView(View view) {
if (mRecyclerAdapter != null) {
mRecyclerAdapter.removeHeaderView(view);
}
}
/**
* 移除
*
* @param view
*/
public void removeFooterView(View view) {
if (mRecyclerAdapter != null) {
mRecyclerAdapter.removeFooterView(view);
}
}
}
3.使用
1 | public class MainActivity extends AppCompatActivity { |
4.效果