装饰器模式:
装饰器模式(Decorator Pattern)又名装饰者,是项目中比较常用的一种设计模式(结构型模式)。其特点:在不改变原有类结构的同时,可以动态给其添加行为、功能,大家都知道编程做到一定程度,我们考虑的不仅是功能实现,更注重其结构清晰,易于维护。下面我们看一个小例子,最后来理解下装饰器的设计初衷及其特点。
step1
移动电子时代,相信大家衣食住行都离不开电子屏幕。例:手机、电脑、TV、手表等等,说到这里我们都知道每一个电子屏幕上多多少少都会有一些静态页面,假设屏幕上的每一个视图都由一个个view组成,通过draw函数将具体的图形画在屏幕上。为了其通用性,我们现在抽象出一个IShap接口,draw函数是对所有图形行为的高度抽象。
public interface IShape {
void draw();
}
step2
step1定义了一个IShape(图形)接口,具体细节由子类去实现。CircleImpl (圆)是IShape的一个实现类并重写了draw函数,这里做一个简单打印,假设其内部是在屏幕画了一个圆形。RectangleImpl (长方形)同理。
图形:圆
public class CircleImpl implements IShape{
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("Shape:Circle");
}
}
图形:长方形
public class RectangleImpl implements IShape{
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("Shape:Rectangle");
}
}
step3
AbsShape 是IShape的实现类,在装饰器模式中具有承上启下的作用。
public abstract class AbsShape implements IShape{
IShape shapeDecorated;
public AbsShape (IShape shapeDecorated) {
this.shapeDecorated = shapeDecorated;
}
@Override
public void draw() {
// TODO Auto-generated method stub
shapeDecorated.draw();
}
}
step4
BorderDecorator 此模式的核心类!此类中的代码十分关键请认真阅读:
public class BorderDecorator extends AbsShape{
public BorderDecorator(IShape decoratedShape) {
super(decoratedShape);
// TODO Auto-generated constructor stub
}
@Override
public void draw() {
// TODO Auto-generated method stub
super.draw();
drawRedBorder(shapeDecorated);
}
/**
* 装饰器模式动态拓展的功能,画边框
* @param decoratedShape
*/
private void drawRedBorder(IShape decoratedShape) {
System.out.println("setRedBorder");
}
}
ok,看到这里我默认你已经认真的读完BorderDecorator类的每一个字符了,下面开始我们的分析:
1.draw()
2.drawRedBorder()
draw():通过draw函数里的super.draw()我们能知道它默认会调用父类(AbsShape、IShape)的draw函数,随后调用CircleImpl、Rectangle的draw函数。这里我们牵伸出一个关键字super,此标识的作用是当子类重写父类的函数时,且调用了super.xxx函数,意思是执行本身函数的同时也会调用父类的xxx函数。
drawRedBorder():此函数中主要是对IShape的完善,在draw函数调用的同时新增Border(边框),这里做简单打印prinln("drawRedBorder")。
step5
到这里装饰器模式所用到的代码就完成了,我们看下面测试代码,然后去结果领取最终奖励。
public class DecoratorTest {
public static void main (String[] args) {
//为圆形构建边框装饰器
IShape redCircle = new BorderDecorator(new CircleImpl());
//为长方形构建边框装饰器
IShape redRectangle = new BorderDecorator(new RectangleImpl());
redCircle.draw();
redRectangle.draw();
}
}
结果:
控制台打印信息如下:
--> Shape:Circle
--> drawRedBorder
-->Shape:Rectangle
-->drawRedBorder
ok,继续开始我们的分析:new BorderDecorator(new CircleImpl()).draw()
- 创建BorderDecorator(边框装饰器)
- 传入CircleImpl(圆)
- 调用BorderDecorator的draw函数
这里对draw函数进行解析:
由于BorderDecorator、AbsShape、CircleImpl、RectangleImpl都是IShape的直接或间接子类,且都重写了draw函数,所以当我们调用BorderDecortor的draw函数时,它会去执行IShape、AbsShape、CircleImpl、RectangleImpl的draw函数,同时由于BorderDecorator对draw函数进行了拓展,也就是调用draw函数的同时动态的给IShape添加了功能。
有点绕,慢慢理一下思路。ok,这就是装饰器模式动态添加功能的实现了。
总结:
装饰器模式:就是通过一个类对原有类进行包装,并对功能(函数)进行拓展,同时不改变原有类的结构。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,随着扩展功能的增多,子类会很膨胀。
何时使用:在不增加很多子类的情况下扩展功能。
关键代码:super关键字,共同的父类。
优点:装饰模式是继承的一个替代模式,可以动态地扩展一个类的功能,且不会相互耦合。
缺点:需要对基类进行装饰,如果此类过多,实现上比较复杂。
单例-->http://www.jianshu.com/p/137593180979
模板--> http://www.jianshu.com/p/2f1964f98e44
观察者-->http://www.jianshu.com/p/0cf09f160f91
喜欢有帮助的话: 双击、评论、转发,动一动你的小手让更多的人知道!关注 帅比-杨