装饰模式

之前一直不是很清楚装饰模式,今天把设计模式重新看了下发现也没有多么难。总结一下,装饰器模式就是允许用户向现有对象添加新功能,而无需更改其结构。该模式通过创建一个包装原始类(Component)的装饰器类(Decortator),并提供其他功能,以保持类方法的签名完整。如下图:
装饰模式类图
下面举一个例子:
假设我们想要计算一下买房+装修的花费。房子有一室一厅、两室一厅等,装修的话需要灯、床、桌子、椅子等等。当然如果不用装饰模式的话想计算任意组合都需要单独实现一个类,比如一个带一张桌子的一室一厅需要新建一个OneBedroomWithOneTable类,如果又想要知道带两张桌子的一室一厅的话有需要新建另一个OneBedroomWithTwoTable类,如果想知道任意一种组合方式的花费就需要为每一种排列组合的都实现一个单独的类,这样肯定是不行的。这时候就可以使用装饰模式来解决了。

首先,定义一个抽象房屋类作为原始类:

public abstract class Apartment {

    //房屋描述
    public abstract String getDescription();

    //房屋花费
    public abstract double getCost();
}

通过这个原始类我们可以两个的房屋的实现类:

public class OneBedroom extends Apartment {

    @Override
    public String getDescription() {
        return "一室一厅";
    }

    @Override
    public double getCost() {
        return 3000000;
    }
}
public class TwoBedroom extends Apartment {

    @Override
    public String getDescription() {
        return "两室一厅";
    }

    @Override
    public double getCost() {
        return 4000000;
    }
}

OK,接下来我们需要对房屋进行装修的话需要定义一个装饰类,也就是所有房屋装饰的基类,此类必须继承自 Apartment :

public abstract class Decoration extends Apartment {

    protected Apartment apartment;

	//这里需要传入房屋类,可根据需要传入未装饰过得房屋或者已经装饰过得房屋
    public Decoration(Apartment apartment){
        this.apartment = apartment;
    }

    public String getDescription() {
        return apartment.getDescription();
    }

    public double getCost() {
        return apartment.getCost();
    }
}

然后我们可以在Decoration的基础上实现不同的装饰:

public class Bed extends Decoration {
    
    public Bed(Apartment apartment){
        super(apartment);
    }

    @Override
    public String getDescription() {
        return apartment.getDescription() + " + 床";
    }

    @Override
    public double getCost() {
        return apartment.getCost() + 500;
    }
}
public class Light extends Decoration {

    public Light(Apartment apartment) {
        super(apartment);
    }

    @Override
    public String getDescription() {
        return apartment.getDescription() + " + 灯";
    }

    @Override
    public double getCost() {
        return apartment.getCost() + 100;
    }
}
public class Table extends Decoration {

    public Table(Apartment apartment){
        super(apartment);
    }

    @Override
    public String getDescription() {
        return apartment.getDescription() + " + 桌子";
    }

    @Override
    public double getCost() {
        return apartment.getCost() + 80;
    }
}

最终的计算:

public static void main(String[] args) {

        //首先买一个一室一厅
        Apartment apartment = new OneBedroom();
        //装修个灯
        apartment = new Light(apartment);
        //再买张桌子
        apartment = new Table(apartment);
        //再配张床
        apartment = new Bed(apartment);
        
        //一室一厅 + 灯 + 桌子 + 床; 花费: 3000680.0
        System.out.println(apartment.getDescription() + "; 花费: " + apartment.getCost());
    }

最终的类图如下(可以对比下第一张图):
房屋装饰器模式类图
Java IO使用的就是典型的装饰模式:
Java IO架构图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值