java 装饰者模式_java常用设计模式(四)装饰者模式

设计模式第四篇,装饰者模式,大家多多指教。

简介

装饰者模式是动态的将责任附加到对象上(引自《Head First设计模式》)。这里的重点在于动态这两个字,我们都知道继承的实现的方式,它是是类编译的时候就去加载文件,属于一种静态的附加,而我们要实现动态的附加就不能单纯的通过继承来实现。在这种背景下,装饰者模式就应运而生了。装饰者模式的实现:首先所有的类都有一个共同的抽象,这个抽象可以是一个抽象类,也可以是一个接口,所有的类该抽象的子类或者实现。语言描述比较抽象,下面我们通过一个例子来描述该模式。

例子

我们举一个吃火锅的例子,根据装饰者模式的特点:

首先我们要有个共同的抽象,这里我们通过接口来实现,这个接口我们称之为锅底。

/** 锅底*/

public interfaceHotpot {/**描述*/String getName();/**价格*/Double getPrice();

}

第二步,我们设计具体的锅底类,我们分为酱香锅、香辣锅和清汤锅,这是底锅,每笔单都必须有且只有一个。

public class JamHotpot implementsHotpot{

@OverridepublicString getName() {return "酱香锅";

}

@OverridepublicDouble getPrice() {return 4.0;

}

}public class SpicyHotpot implementsHotpot{

@OverridepublicString getName() {return "香辣锅";

}

@OverridepublicDouble getPrice() {return 4.0;

}

}public class ClearSoupHotpot implementsHotpot{

@OverridepublicString getName() {return "清汤锅";

}

@OverridepublicDouble getPrice() {return 3.0;

}

}

第三步,我们新增一个配菜接口,继承共同的接口锅底,这个接口用来作为所有配菜的父级,该接口可以拓展所以配菜的共有属性

/** 配菜*/

public interface SideDish extendsHotpot {//可拓展配菜的公共属性

}

第四步,我们需要新增具体的配菜类,这里的配菜类我们注意到比锅底类多了成员变量和构造方法,而且getName和getPrice方法多了加了传入参数,这个就是为了动态的去附加功能,具体怎么实现参考最后一步。

/** 牛肉*/

public class Beef implementsSideDish {privateHotpot hotpot;publicBeef(Hotpot hotpot) {this.hotpot =hotpot;

}

@OverridepublicString getName() {return hotpot.getName() + ",牛肉";

}

@OverridepublicDouble getPrice() {return hotpot.getPrice() + 38.0;

}

}/** 生菜*/

public class Lettuce implementsSideDish {privateHotpot hotpot;publicLettuce(Hotpot hotpot) {this.hotpot =hotpot;

}

@OverridepublicString getName() {return hotpot.getName() + ",生菜";

}

@OverridepublicDouble getPrice() {return hotpot.getPrice() + 8.0;

}

}

最后我们测试:

public classDecoratorTest {public static voidmain(String[] args) {

System.out.println("=======酱香锅底加牛肉");

Hotpot hotpot= newJamHotpot();

hotpot= newBeef(hotpot);

hotpot= newLettuce(hotpot);

System.out.println("===火锅的价格为:" + hotpot.getPrice() + "元");//如果我们需要更多的配菜参考上面的方式去添加更多的配菜

}

}

总结

如上面所描写的那样,我只需要前台传递给我们所点的锅底和配菜,我们后台去动态的生成一个新的火锅对象。这么设计的好处的拓展极其方便,就算这个火锅店加了新的锅底,或者是配菜,对我们之前的代码是没有任何影响的,这就是所谓的开闭原则(对拓展开放,对修改关闭),后面我们会讲到设计模式相应的原则。除了上面的好处之外,装饰者模式也有他本身不能忽视的问题,那就是每次生成一笔订单都会生成很多小对象,如果该笔单对象很多的话,对我们的内存是个不小的考验,而且过多的小类会让我们的系统变得很复杂,让人很难以理解。所以装饰器模式有利有弊(更多的是利大于弊),我们可以好好思考装饰者模式应用场景,然后进一步掌握这种设计思想。

番外

想了解装饰者模式的更多详细信息可以通过jdk源码或者spring源码去了解。jdk中IO操作就有通过装饰者模式实现的,FilterInputStream和它的实现就是一个装饰者模式,同样的在spring源码中,凡事以Decorator结尾的类都是实现的装饰者模式,当然不是所有的装饰器模式都是以Decorator结尾的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值