设计模式系列:装饰者模式

引入

1.案例

  比如,三个继承关系:Father,Son,GrandSon三个类,我要在son类上增加一些功能怎么办?

2.面向实现编程方案

  修改Son,这种方案会有大问题,因为你增强的功能是是修改Son的方法还是增加Son的方法,是否会对GrandSon造成影响呢?

3.面向设计编程方案

  通过建立SonDecorator类来修饰Son类,相当于创建了一个新的类,这个对原有程序没有改变,通过扩展很好的完成了这次变更。

其实下面的代码案例并不是非常好,容易让人理解错误。以改需求为例:
建立SonDecorator,把Son的对象传递给SonDecorator,这样可以保证Son的功能不会丢失,然后在SonDecorator中增加一个新的功能即可,比如新增加一个方法a(),这个方法是和Son没有关系的。

一.名称

二.问题(为了解决什么问题)

  • 一个子系统需要对外提供服务
  • 需要扩展一个类的功能,或给一个类增加附加功能。
  • 需要动态的给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。

三.解决方案(主要体现在uml和核心代码上)

装饰模式是对继承的有力补充,你要知道继承不是万能的,继承可以解决实际的问题,但是在项目中你要考虑诸如易维护、易扩展、易复用等,而且在一些情况下(比如上面那个成绩单例子)你要是用继承就会增加很多子类,而且灵活性非常差。而装饰模式就有一个非常好的优点:扩展性非常好。

装饰者模式主要体现的扩展,通过包一层来扩展(与增加一层类似)。

体现的原则:无

这里写图片描述

这里写图片描述

通用代码:

这里写图片描述

这里写图片描述

这里写图片描述

四.例子

成绩单装饰:
基本类:

/**
 * Created by annuoaichengzhang on 16/3/26.
 */
public abstract class SchoolReport {
    public abstract void report();
    public abstract void sign(String name);
}

装饰类:

/**
 * Created by annuoaichengzhang on 16/3/26.
 */
public class Decorator extends SchoolReport {
    private SchoolReport sr;

    public Decorator(SchoolReport sr) {
        this.sr = sr;
    }

    // 保证装饰者类还有SchoolReport的功能
    @Override
    public void report() {
        this.sr.report();
    }

    @Override
    public void sign(String name) {
        this.sr.sign(name);
    }
}
/**
 * Created by annuoaichengzhang on 16/3/26.
 */
public class HightScoreDecorator extends Decorator {
    public HightScoreDecorator(SchoolReport sr) {
        super(sr);
    }

    @Override
    public void report() {
        super.report();
    }

    // 装饰者类新增加的功能
    private void reportHightScore() {
        System.out.println("这次语文最高是75,数学是78,自然是80");
    }
}
/**
 * Created by annuoaichengzhang on 16/3/26.
 */
public class SortDecorator extends Decorator {
    public SortDecorator(SchoolReport sr) {
        super(sr);
    }
    // 装饰者类新增加的功能
    private void reportSort() {
        System.out.println("我的排名第38名.....");
    }

    @Override
    public void report() {
        super.report();
    }
}

Client:

public class Client {
    public static void main(String[] args) {
        SchoolReport sr = null;

        sr = new FouthGradeSchoolReport();
        sr = new HightScoreDecorator(sr);
        sr.reportHightScore();
        sr = new SortDecorator(sr);
        sr.sign("老爸");

    }
}

五.效果(有啥优缺点)

这里写图片描述

常见案例

带滚动条的窗体

多重数据加密系统。用户使用最简单的加密算法觉得不行,还可以吧加密后的结果使用其他加密算法进行二次加密,当然也可以进行三次加密。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值