我要六一儿童节礼物!!DecoratorPattern----装饰模式

六一儿童节到了,今天我来为大家讲解一下DecoratorPattern!我觉得用这个例子来讲解这个模式再合适不过了!


我们先来看看装饰模式的概念:动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加灵活。


我们来进入场景:

明天就是儿童节了,你准备给你邻居的孩子准备了一个玩具汽车!多么激动人心的礼物啊!买这个汽车,我们需要花费一定的费用,下图是汽车的对象:


其中descreption是对该类的一个描述,这里是"car",cost是对该类的一个花费的金额,为250元。

但是,光送一个车总会显得不够高大上,所以,我们需要给他一个包装盒子,盒子的对象如下:


盒子的描述是"box",价值是5元(软妹币符号忘记画了,无伤大雅)。

现在,我们需要将汽车装入盒子中,那么怎么装入呢??

也许我们会想到:1.现有汽车类,2.让盒子类继承汽车类,这样,我们可以在盒子类中重写description和cost了,如下图:


此时的description和cost都是 盒子+汽车  后形成的。此时的description是"car  with box ",cost是255元。



当然,你送礼物给邻居小孩,光一个盒子抱住汽车总感觉单调了一些,因此,你想增加一点东西:在盒子外面系上一条彩带打成蝴蝶结的样子!

那么,彩带的对象如下图:


此时,desription="car with box with ribbon";  cost= 255.5 ;


这样我们的礼物就包装好了!!

但是回到程序中,如果有一个程序是让你制作礼物,提供给你一个car类和许许多多其他的装饰类,如ribbon,box,flower....等等,,不同的人需要不同的包装成分,加上如果装饰类过多,这会使得我们的最终礼物要不停继承,不停继承。并且最终的礼物只能静态地生成,无法动态地“包装”。那么我们如何做到动态地包装呢??


下面,我们用到了装饰模式!

我们以这个六一儿童节礼物为例画个类图:


最上面是一个Gift礼物的抽象类,他里面有description()和cost()两个方法。MainGift类是我们要送的主要的礼物,比如这里的汽车,还有decorator类是用来包装的装饰类,它们都继承自Gift,这样可以让装饰品在装饰我们汽车的时候,它仍然是一个Gift。

下面我们看看代码部分:

我们先定义Gift类:

public abstract class Gift{
  String description="null";
  public Strinig Description(){
     return description;//返回对象的描述
  }
  public abstract double cost();//抽象方法,子类中实现
}
下面是装饰类:

public abstract class Decorator extends Gift{//定义抽象类--装饰类
  public abstract String Description();//此时继承了Gift,但是又把该方法变成抽象的,为了在定义包装的时候,重写描述!!不懂可以继续看下面
}

下面,我们的第一个礼物

public class Car extends Gift{
  public Car(){
    description="a car";//注意,这里修改了description属性!!
  }
  public double cost(){
    return 250;//车的价格
  }
}


这个MainGift这里就是Car,它继承Gift类,很简单。下面我们来看看装饰类!要注意思考!

首先是box对象

public class Box extends Decorator{
  Gift gift;//用来实例化MainGift的变量!
  public Box(Gift gift){
    this.gift = gift;//可以在构造的时候就包装一个Gift!
  }
  public String Description(){
    return gift.Description()+" with a box";
  }
  public double cost(){
    return 5+gift.cost();//返回盒子的价格加上它所包装的MainGift的价格
  }
}
ribbon彩带是一样的,代码如下:

public class Ribbon extends Decorator{
  Gift gift;//用来实例化MainGift的变量!
  public Box(Gift gift){
    this.gift = gift;//可以在构造的时候就包装一个Gift!
  }
  public String Description(){
    return gift.Description()+" with a ribbon";
  }
  public double cost(){
    return 0.5+gift.cost();//返回彩带的价格+它所包装的Gift的价格(这里后面也会讲到,包装的是car+box)
  }
}


下面我们在看看如何使用这些类:使用它们的代码如下:

public static void main(String args[]){
  Gift gift = new Car();//这里的类型上转我不在多叙述,不懂得可以先看看这方面的知识再回头看我们这个。(我还是多叙述一下:可以将抽象类的具体实现类的对象赋值给抽象类对象)
  System.out.println(gift.Description()+" 价格:"+gift.cost());
  gift = new Box(gift);//将gift自己(Car)包装给box
   System.out.println(gift.Description()+" 价格:"+gift.cost());
  gift = new Ribbon(gift);//将car+box 为一个整体,包装给ribbon
   System.out.println(gift.Description()+" 价格:"+gift.cost());
}

上面就是我们的装饰模式。它可以很灵活的动态添加新的功能。通过在装饰类里面添加一个组件(gift),每次包装只管自己的任务和它所包装的一个整体,而不去关心它所包装的整体里面又具体有什么。


以上就是装饰模式了,不懂得欢迎大家留言提问。祝大家六一儿童节快乐!!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值