java设计模式-装饰器模式(包装模式)

装饰器模式:在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰器模式的使用过程:
1.创建一个接口,然后写方法
2.创建类实现该接口,并实现接口里的方法
3.创建包装类,也实现上面的接口和方法
4.在包装类中声明被包装类的类型,通过构造器的方式注入
5.在包装类中,不需要修改的方法,直接调用被包装类的方法即可,只需要修改的自己关注的方法。

代码示例
1.创建接口Ups,并声明了3个方法

public interface Ups {
    void start();
    void stop();
    void work();
}

2.写实现类SimpleUps

/**
 * 普通ups
 */
public class SimpleUps implements Ups{

    @Override
    public void start() {
        System.out.println("开始启动..");
    }

    @Override
    public void stop() {
        System.out.println("停止工作..");
    }

    @Override
    public void work() {
        System.out.println("工作中..");
    }
}

3.创建包装类,对SimpleUps的start方法进行增强,为了代码的可扩展性,我们传入的是SimpleUps对应的接口,而不是具体的实现类

/**
 * 高级ups
 */
public class SinorUps implements Ups{

    private Ups ups;

    public SinorUps(Ups ups) {
        this.ups = ups;
    }

    @Override
    public void start() {
        System.out.println("开始启动前检查一下..");
        this.ups.start();
    }

    @Override
    public void stop() {
        System.out.println("停止工作..");
    }

    @Override
    public void work() {
        System.out.println("工作中..");
    }
}

4.代码测试和结果输出

public class TestUps {
    public static void main(String[] args) {
        Ups ups = new SinorUps(new SimpleUps());
        ups.start();
    }
}


可以看出在被包装类的基础上多输出了我们自己增加的。

对上面的代码,我们可以做一下改动,加一层抽象类AbstractUps,

public abstract class AbstractUps implements Ups{
    private Ups ups;

    public AbstractUps(Ups ups) {
        this.ups = ups;
    }
    @Override
    public void start() {
        this.ups.start();
    }

    @Override
    public void stop() {
        this.ups.stop();
    }

    @Override
    public void work() {
        this.ups.work();
    }
}

修改SinorUps类,只增强我们需要关注的方法

/**
 * 高级ups
 */
public class SinorUps extends AbstractUps{

    public SinorUps(Ups ups) {
        super(ups);
    }

    @Override
    public void start() {
        System.out.println("开始启动前检查一下..");
        super.start();
    }

}

输出测试

public class TestUps {
    public static void main(String[] args) {
        Ups ups = new SinorUps(new SimpleUps());
        ups.start();
        System.out.println("=============================");
        ups.work();
    }
}



从上面可以看出,装饰类并没有对原始类做任何修改和破坏,也没有继承原始类。如果还有类实现类Ups接口,需要对start方法做同样的增强,则只需要在Ups ups = new SinorUps(new SimpleUps());传入需要增强的实例对象即可。例如创建SimpleUpsV2实现Ups接口

**
 * v2版本ups
 */
public class SimpleUpsV2 implements Ups{

    @Override
    public void start() {
        System.out.println("v2版本开始启动..");
    }

    @Override
    public void stop() {
        System.out.println("v2版本停止工作..");
    }

    @Override
    public void work() {
        System.out.println("v2版本工作中..");
    }
}

对start方法做同样的增强

public class TestUps {
    public static void main(String[] args) {
        System.out.println("================V2版本=============");
        Ups upsV2 = new SinorUps(new SimpleUpsV2());
        upsV2.start();
    }
}



上述方法如果用继承的方式实现,则需要分别创建Simple和SimpleV2的子类,若Ups的接口的子类非常多的话,且都需要对某一方法做同样的增强,用继承的方式去实现,就需要创建非常多的子类,代码会很庞大。

继承与装饰器总结

1.装饰器模式比继承要灵活。避免了继承体系臃肿

2.装饰器模式降低了类于类之间的关系。

3.用装饰器实现的功能,继承能否实现,是可以的,但是在代码的结构层次上来说,装饰器模式比继承灵活了很多。

4.装饰模式与继承关系的目的都是要拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者“除掉”一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值