设计模式之装饰模式及使用

装饰模式介绍

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案

使用场景:

替代继承,扩展一个类的功能
动态的给一个对象添加功能,以及动态的撤销该功能

优点:

动态扩展一个实现类的功能,在不需要添加功能的时候,可以撤销装饰。
装饰类和被装饰类模块间,通过抽象产生依赖,不会相互耦合
装饰模式替换继承,可以避免继承链的子类被影响

源码哪里用到了装饰模式

Java I/O 中的装饰者模式
字符流(InputStream/OutputStream) 和 字节流(Reader/Writer)
Spring Session 中的装饰者模式
ServletRequestWrapper(Response也一样)的装饰者模式
Mybatis 缓存中的装饰者模式
Cache为抽象构件类,PerpetualCache为具体构件类,decorators包下的类为装饰类,这里没有抽象装饰类。

装饰模式与代理模式的区别

装饰模式:侧重给一个实现类动态添加功能,不会对实现类的方法进行过滤拦截
代理模式:侧重将一个实现类的功能,委托给代理类来处理,可以对实现类的方法进行过滤拦截

装饰模式实现

定义一个接口Human,代码如下:

public interface Human {
    public void run();
}

抽取一个抽象方法run,人类是可以跑步的,定义一个被装饰的类Man,代码如下:

public class Man implements Human {
    @Override
    public void run() {
        System.out.println("人会跑步");
    }
}

定义一个装饰的抽象类,代码如下:

public abstract class AbstractDecorator implements Human{
    //持有被装饰类的引用 
    private Human human;

    //构造函数注入被装饰者
    public AbstractDecorator(Human human) {
        this.human = human;
    }

    //调用被装饰类的方法
    @Override
    public void run() {
        human.run();
    }
}

定义一个装饰的实现类,代码如下:

public class ManDecorator extends AbstractDecorator {
    public ManDecorator(Human human) {
        //调用父类的构造方法
        super(human);
    }

    //装饰类增加的功能
    private void fly() {
        System.out.println("人可以飞");
    }

    //增强了功能的run方法
    @Override
    public void run() {
        super.run();
        fly();
    }
}

客户端代码如下:

public class Client {
    public static void main(String[] args) {
        //创建被装饰的类
        Human human = new Man();

        //创建装饰的类,并添加被装饰类的引用
        Human superMan = new ManDecorator(human);

        //执行增强后的run方法
        superMan.run();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值