每日设计模式——装饰器模式

装饰器模式

装饰器模式是一个比较常见的模式,其主要是动态的给一个对象添加一些额外的职责。但从给对象增加职责来说,使用继承也能够实现,但是正如《head first大话设计模式》中那样,单纯的继承会造成“类爆炸”的问题,同时继承也不够灵活,很难做到对扩展开放,对修改关闭。所以,从这个角度来说,装饰模式相比生成子类来说更为灵活。

装饰模式的类图结构如下:

在类图中,包含四个部分的角色,Component抽象组件,它是一个接口或者抽象类,定义最核心的对象,是所有类的超类;ConcreateComponent:具体的构件,是最核心,最原始,最基本的接口或者抽象类的实现,我们要装饰的对象就是它;Decorator:装饰角色,一般是一个抽象类,实现接口或者抽象方法,它里边不一定有抽象方法,但是一定有一个private变量指向Component抽象构件;具体装饰角色ConcreateDecorator1和ConcreateDecorator2是两个具体的装饰类,把最核心,最原始,最基本的东西装饰成其他的东西。

首先,来看一个例子。我们购买一套别墅,然后分别对别墅进行装修(增加餐厅、卧室等)。其代码实现如下:

public class Test {
    public static void main(String[] args) {
        //拥有一个餐厅的别墅
        Room room = new VillasHouseWithDailingRoom(new VillasHouse());
        System.out.println(room.getCost());
        //拥有一个餐厅,一个卧室的别墅
        room = new VillasHouseWithBedRoom(room);
        System.out.println(room.getCost());
        //拥有一个餐厅,两个卧室的别墅
        room = new VillasHouseWithBedRoom(room);
        System.out.println(room.getCost());

    }
}

/**
 * 房子的抽象类
 */
abstract class Room {
    protected abstract int getCost();
}

/**
 * 抽象类,表示空房子
 */
abstract class House extends Room {

}

/**
 * 具有不同房间的房子
 */
abstract class RoomHouse extends Room {
    private Room room;

    public RoomHouse(Room room) {
        this.room = room;
    }

    @Override
    protected int getCost() {
        return room.getCost();
    }
}

/**
 * 空别墅,100万一套
 */
class VillasHouse extends House {

    @Override
    protected int getCost() {
        return 100;
    }
}

/**
 * 具有一个餐厅的别墅,装修一个餐厅10万
 */
class VillasHouseWithDailingRoom extends RoomHouse {

    public VillasHouseWithDailingRoom(Room room) {
        super(room);
    }

    @Override
    protected int getCost() {
        return super.getCost() + 10;
    }
}

/**
 * 具有一个卧室的别墅,装修一个卧室20万
 */
class VillasHouseWithBedRoom extends RoomHouse {

    public VillasHouseWithBedRoom(Room room) {
        super(room);
    }

    @Override
    protected int getCost() {
        return super.getCost() + 20;
    }
}

 其类图结构如下:

我们首先定义了一个超类Room类,表示所有房子,然后定义了一个VillasHouse类继承了Room类,VallasHouse就是我们的ConcreateComponent,就是我们需要装饰的对象;接着定义了一个抽象类(装饰器类):RoomHouse,表示具有某种房间的房子,接着定义了两个具体的装饰器类:VillasHouseWithDailingRoom和VillasHouseWithBedRoom。最后在Test(Client)类中对VillasHouse进行了装饰,使得VallasHouse具有了餐厅和卧室(给VallasHouse增加了新的功能)。

装饰器模式的优点

装饰类和被装饰类可以独立发展而不会相互耦合;

装饰模式是继承关系的一个替代方案,我们看装饰类Decorator,不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。

装饰器模式可以动态的扩展一个类的功能。

装饰器模式的使用场景

需要扩展一个类的功能或者给一个类增加附加功能;

需要动态的给一个对象增加功能,这些功能可以再动态的撤销;

需要为一批发兄弟类进行改装或者加装功能。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值