什么是装饰器模式
装饰器模式是一种结构型设计模式,是一种动态的包装原有对象的行为。装饰器模式通过增加或修改现有类的功能,使得在不改变原有类的情况下,可以动态地扩展其功能特性。这种模式是一种包装模式,即利用对象组合为原始对象提供功能增强的方式。
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
为什么使用装饰器模式
一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
利用装饰器模式,可以通过一种更加灵活、更加动态的方式,为对象添加功能特性,而不是通过继承来实现功能扩展。使用装饰者模式,我们可以尽可能地减少代码的重复性,提高代码的可复用性和可维护性。
工作中用在哪里
在不想增加很多子类的情况下扩展类。
在Android中,装饰器模式被广泛应用在系统各种View的Drawable中。例如,我们可以通过LayerDrawable来实现多个Drawable的组合,并且还可以通过改变透明度、旋转角度等方式来实现动态效果。
设计思路
装饰器模式的核心思路是通过多个装饰器来动态地扩展对象的功能特性。装饰器模式包含四个角色:
1)抽象组件(Component):定义了对象需要实现的接口。
2)具体组件(ConcreteComponent):实现了抽象组件的接口,并且定义了需要扩展的基本实现方式。
3)抽象装饰器(Decorator):继承自Component,它需要持有一个Component的实例,从而可以对Component进行功能扩展。
4)具体装饰器(ConcreteDecorator):实现抽象装饰器的接口,对Component进行实际的功能扩展。
代码实现
下面给出一个Android中常见的Drawable装饰器的实现代码:
public class CircleDrawable extends Drawable {
private Paint mPaint;
private Drawable mDrawable;
public CircleDrawable(Drawable drawable) {
mDrawable = drawable;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
public void draw(@NonNull Canvas canvas) {
Rect bounds = getBounds();
canvas.drawCircle(bounds.centerX(), bounds.centerY(),
Math.min(bounds.width(), bounds.height()) / 2, mPaint);
mDrawable.setBounds(bounds);
mDrawable.draw(canvas);
}
@Override
public void setAlpha(int alpha) {
mDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
mDrawable.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return mDrawable.getOpacity();
}
}
在这个例子中,CircleDrawable是一个装饰器,它持有一个Drawable的实例,对Drawable进行圆形裁剪的功能扩展。通过继承Drawable,并实现其接口,CircleDrawable可以动态地扩展Drawable的功能特性,而且还可以嵌套使用多个装饰器,实现更加复杂的功能。
总结
装饰器模式是一种灵活、动态的扩展对象功能的设计模式。在Android中,装饰器模式被广泛应用在View的Drawable中,从而实现各种控件的外观、动态效果等功能特性的扩展。装饰器模式通过四个角色来实现功能特性的动态扩展,包括抽象组件、具体组件、抽象装饰器和具体装饰器。使用装饰者模式,我们可以尽可能地减少代码的重复性,提高代码的可复用性和可维护性。