设计模式学习——装饰者模式

当我们来到KFC开始点餐的时候,一开始还不是特别有胃口,所以只点了一份汉堡套餐,有一份汉堡和饮料,但后来又点了一份薯条,最后干脆再点一份炸鸡腿,那么如何来计算我们花了多少钱呢?

在这个场景下,装饰者模式会起到很好的效果。


装饰者模式

定义:动态的将责任附加到对象身上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

即通过将装饰者和组件组合的方式,来加入新的行为。行为来自装饰者和组件的组合,或者是装饰者和其他装饰者之间的组合关系。

UML类图

  • 组件:具体组件和装饰者需要实现的超类
  • 具体组件:我们将要动态的加上新行为的对象(被包在最里面)
  • 装饰者:每个装饰者都包装着一个组件
  • 具体装饰者:装饰者加上新的方法,即新行为来扩展。

例子

就以一开始举的KFC为例子

KFCFood接口

package decorator;

public abstract class KFCFood {
    private String des = "我是KFC里所有食物(包括饮料)的父类";

    public String getDes() {
        return des;
    }
    
    public abstract double cost();
}

一汉堡一饮料套餐

package decorator;

/**
 * 套餐
 */
public class Setmeal extends KFCFood{
    private Hamberger hamberger;
    private Cola cola;

    public Setmeal() {
        des = "a kind of cheap set meal";
    }

    @Override
    public double cost() {
        return 15;
    }
}

装饰者接口

package decorator;

/**
 * 小食接口
 */
public abstract class Refreshments extends KFCFood{
    public abstract String getDes();
}

具体实现类

package decorator;

/**
 * 具体装饰者,包含着被装饰的对象
 * 被装饰对象可以是具体实现类,也可以是另一个装饰者
 */
public class FrenchFries extends Refreshments {
    KFCFood kfcFood;

    public FrenchFries(KFCFood kfcFood) {
        this.kfcFood = kfcFood;
    }

    @Override
    public String getDes() {
        return kfcFood.getDes() + ",French fries";
    }

    @Override
    public double cost() {
        return 5 + kfcFood.cost();
    }
}
package decorator;

/**
 * 具体装饰者,包含着被装饰的对象
 * 被装饰对象可以是具体实现类,也可以是另一个装饰者
 */
public class Drumstick extends Refreshments{
    KFCFood kfcFood;

    public Drumstick(KFCFood kfcFood) {
        this.kfcFood = kfcFood;
    }

    @Override
    public String getDes() {
        return kfcFood.getDes() + ",Drumstick";
    }

    @Override
    public double cost() {
        return 10 + kfcFood.cost();
    }
}

测试

package test.decorator;

import decorator.Drumstick;
import decorator.FrenchFries;
import decorator.KFCFood;
import decorator.Setmeal;

public class test {
    public static void main(String args[]){
        KFCFood setmeal = new Setmeal();
        KFCFood frenchfries = new FrenchFries(setmeal);
        KFCFood drumstcik = new Drumstick(frenchfries);
        System.out.println(drumstcik.cost());
        System.out.println(drumstcik.getDes());
    }
}

小结

装饰者模式符合了组合原则外,还符合这么一条原则:

对扩展开放,对修改关闭

 

  • 装饰者模式可以在被装饰者的行为前或者后面添加上自己的行为,甚至将被装饰者的行为整个替换掉,而达到特定的目的。
  • 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
  • 装饰者会导致设计中出现许多小对象,如果过度使用,将使程序变得很复杂。

源码在这里:我的github地址

其他设计模式:设计模式学习笔记​​​​​​​


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值