设计模式 - 装饰器模式

装饰器模式:属于结构型设计模式,是比较简单,常见的设计模式之一。主要的目的是给现有的类加一层装饰

定义

允许向一个现有的对象添加新的功能,同时不改变它的结构,即动态地给一个类添加额外职责
换成大白话的说法就是,身为一个吃货的你,给你手上的那个热狗,加上香肠加上鸡蛋加上蔬菜,会让你的热狗变成真的狗吗?并不会,热狗还是那条热狗。

例子

又到了喜闻乐见的举例子时间,这次发你点福利。假如今天你的女神终于答应跟你约会了,你是不是要好好准备一下。我们来好好说道说道怎么个准备发,直接上码:

/**
 * 要跟女神约会是不好打理一下自己?
 * 先来个 人 的抽象类,并且会打理自己
 */
public interface Person {
    public void dressUp();
}

你要跟女神约会,总该是会打理自己的人吧。总不能邋里邋遢的出门找女神吧

/**
 * 先来个 你
 * 跟女神约会,总得先梳洗一番把,最基础要求,不然你女神被你臭走了怎么办?
 */
public class Man implements Person{

    @Override
    public void dressUp() {
        System.out.println("你梳洗一番");
    }
}

好了,现在模拟一下,跟女神的约会

public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        man.dressUp();
        System.out.println("去跟女神约会");
    }
}

运行结果:
在这里插入图片描述
但是这样真的好吗?难得女神答应你的约会,你就梳洗一番就去了?不打算给女神留下深刻印象吗?不再打扮打扮自己吗?所以,还是得再回炉重造一下。来来来,总得换上一套 帅气的衣服吧。

public class GetClothesMan implements Person{
    private Person person;

    public GetClothesMan(Person person) {
        this.person = person;
    }

    @Override
    public void dressUp() {
        person.dressUp();
        System.out.println("穿上帅气的衣服");
    }
}

再模拟一下约会情景

public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        Person getClothesMan = new GetClothesMan(man);
        getClothesMan.dressUp();
        System.out.println("去跟女神约会");
    }
}

运行结果:
在这里插入图片描述
既然都穿上了帅气的衣服了,不喷点古龙水吗?

public class GetCologne implements Person{
    private Person person = null;

    public GetCologne(Person person) {
        this.person = person;
    }
    @Override
    public void dressUp() {
        person.dressUp();
        System.out.println("喷一下古龙水");
    }
}

public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        Person getClothesMan = new GetClothesMan(man);
        Person getCologne = new GetCologne(getClothesMan);
        getCologne.dressUp();
        System.out.println("去跟女神约会");
    }
}

运行结果:
在这里插入图片描述
当然,你是大户人家的话,可以喷两下

public class Client {
    public static void main(String[] args) {
        Person getDoubleCologne = new GetCologne(new GetCologne(new GetClothesMan(new Man())));
        getDoubleCologne.dressUp();
        System.out.println("去跟女神约会");
    }
}

运行结果:
在这里插入图片描述

使用场景

  • 需要扩展一个类的功能或者给一个类增加附加功能
  • 需要动态地给一个对象增加功能,并且这些功能可以再动态地撤销

注意:虽然装饰器模式可以嵌套多层,但是,多层的装饰是很复杂的,所以尽量减少装饰类的数量,降低系统的复杂度。

小结

以上这种,对一个 已有的对象(梳洗一番的你) 添加 额外的功能(穿上帅气的衣服、喷上古龙水 就是经典的装饰器模式。从上面的例子中你可以看到,一直都是对要去跟女神约会的你进行妆扮(装饰)。

扩展一

装饰器模式代理模式
这两种模式在写法上非常相似。但是还是有所区别的

  • 角色不一样: 装饰器模式,从头到尾,角色是唯一的,都是对已有的对象进行装饰;但是 代理模式 是有2个角色的,代理人和被代理人,他们分管不同的职责。
  • 目的不一样: 装饰器模式 的目的是对已有对象进行额外功能的添加(对自己投资后,还是自己);但是代理模式的目的是对已有对象的访问进行控制(也就是说,代理人决定了女神能不能约你)。
  • 写法不一样: 装饰器模式 需要外部把需要装饰的对象传入,调用者需要知道是对谁进行装饰;但是代理模式,可以不需要从外部传入被代理人对象,调用者不一定需要被代理人是谁,调用者只需要跟代理者打交道。

扩展二

装饰器模式继承
开发遵从的原则里 组合 > 继承装饰器模式就是以组合的方式对对象进行扩展,所以它会比继承更加灵活,更好的写出健壮,可扩展性强的代码。
拿上面的喷古龙水的那一步来当例子,有时需要喷一下,有时需要喷两下。上面装饰器模式的写法,是用同一个喷古龙水的类进行了2次的包装达到了效果;那么如果用继承的写法,就需要创建2个类分别是喷一下的实现和喷两下的实现,这样就会增加类的数量,如果这样的情况多了,会让项目臃肿不好维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值