[design pattern](3) Dectorator
前言
很久没有写关于设计模式的博客了,实在是没有太多的精力去写。但个人觉得设计模式在我们的日常开发中还是挺重要的,它提高了软件的可维护性。因此还是有必要坚持学习设计模式,写博客主要是为了加深我对设计模式的理解。今天我要讲的设计模式是装饰者模式(Dectorator),它是结构型模式的一员。如果有什么讲的不正确的地方,希望各位大佬指正。
思考题
首先,让我们思考下面的问题:
有这么一家奶茶店,希望开发一个计算奶茶价格的软件,当客户点一杯奶茶,并且加入某几样配料时,需要及时的计算出这杯奶茶的价格,下面是奶茶和配料的价格。
原味奶茶:10
珍珠:2
椰果:3
巧克力:5 例子:如果用户点椰果奶茶,那么他的价格就是 原味奶茶+椰果=13。
当没有学习过装饰者模式时,我会给出下面的解决思路:
Ingredient.java:
public interface Ingredient {
Integer price();
}
配料接口:所有的配料都要实现这个接口,该接口有一个价格方法。
Chocolate.java:
public class Chocolate implements Ingredient {
public Integer price() {
return 5;
}
}
Coconut.java:
public class Coconut implements Ingredient {
public Integer price() {
return 3;
}
}
Pearl.java:
public class Pearl implements Ingredient {
public Integer price() {
return 2;
}
}
以上的上我的配料的实现类,他们都实现了 Ingredient 接口,并且实现了 price 方法。
MilkTea.java:
import java.util.List;
import java.util.ArrayList; public class MilkTea {
private List<Ingredient> ingredientList = new ArrayList<>(); public void addIngredient(Ingredient ingredient) {
ingredientList.add(ingredient);
} public Integer countPrice() {
Integer allPrice = 10;
for (Ingredient ingredient : ingredientList) {
allPrice += ingredient.price();
}
return allPrice;
}
}
以上是奶茶类的实现,里面有一个 ingredientList 成员变量,使用 addIngredient 就可以增加配料,调用 countPrice 计算奶茶的价格。
TestMain.java:
public class TestMain {
public static void main(String... args) {
MilkTea milkTea = new MilkTea();
milkTea.addIngredient(new Chocolate());
System.out.println("巧克力奶茶:" + milkTea.countPrice());
MilkTea milkTea_1 = new MilkTea();
milkTea_1.addIngredient(new Coconut());
milkTea_1.addIngredient(new Pearl());
System.out.println("珍珠椰果奶茶:" + milkTea_1.countPrice());
}
}
下面给出该实现的uml类图。

装饰者设计模式
定义:动态的给特定对象赋予新的功能.
类图:

从上面的类图我们可以总结出以下几点:
1.实现装饰者模式,我们需要有一个公共接口,我们的装饰者和被装饰者都需要继承这个接口.
2.为了更好地维护代码,上面将被装饰者的公共的代码提取到了父类中,子类通过继承这个父类可以很容易的实现不同的特性.
3.在父类的接口中实现了 Material 接口,以保证装饰者可以被其他装饰者装饰.
4.父类中有成员变量 Material ,以保证每个装饰者都知道自己装饰的是什么对象.
重构思考题
Material.java:
public interface Material {
Integer price();
}
MilkTea.java:
public class MilkTea implements Material {
@Override
public Integer price() {
return 10;
}
}
Ingredient.java:
public abstract class Ingredient implements Material {
private Material material;
public Ingredient(Material material) {
this.material = material;
}
@Override
public Integer price() {
return material.price() + getPrice();
}
public abstract Integer getPrice();
}
Chocolate.java:
public class Chocolate extends Ingredient {
public Chocolate(Material material) {
super(material);
}
@Override
public Integer getPrice() {
return 5;
}
}
Coconut.java:
public class Coconut extends Ingredient {
public Coconut(Material material) {
super(material);
}
@Override
public Integer getPrice() {
return 3;
}
}
Pearl.java:
public class Pearl extends Ingredient {
public Pearl(Material material) {
super(material);
}
@Override
public Integer getPrice() {
return 2;
}
}
MainTest.java:
public class MainTest {
public static void main(String... args) {
Material milkTea = new Chocolate(new MilkTea());
System.out.println("巧克力奶茶:" + milkTea.price());
Material milkTea_1 = new Coconut(new Pearl(new MilkTea()));
System.out.println("珍珠椰果奶茶:" + milkTea_1.price());
}
}
[design pattern](3) Dectorator的更多相关文章
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 设计模式(Design Pattern)系列之.NET专题
最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...
- [转]Design Pattern Interview Questions - Part 4
Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...
- [转]Design Pattern Interview Questions - Part 2
Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...
- [转]Design Pattern Interview Questions - Part 3
State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...
- [转]Design Pattern Interview Questions - Part 1
Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...
- design pattern
1. visitor design pattern http://butunclebob.com/ArticleS.UncleBob.IuseVisitor
- Design Pattern: Observer Pattern
1. Brief 一直对Observer Pattern和Pub/Sub Pattern有所混淆,下面打算通过这两篇Blog来梳理这两种模式.若有纰漏请大家指正. 2. Use Case 首先我们来面 ...
- Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern
Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming.这其中 ...
随机推荐
- Excel透视表基础之字段布局与重命名、更新、数字格式设置、空值与错误值、
字段布局与重命名 经典布局切换 字段布局 默认布局:文本类型在行区域.数字类型在值区域. 最好用鼠标拖拽. 字段重命名 可以在字段设置中更改. 透视表更新 延迟更新 手动刷新 自动刷新 刷新注意事项 ...
- P1398 [NOI2013]书法家
传送门 就是个普及组 $dp$ 合集,把 $NOI$ 从左到右拆成 $9$ 个部分,每个部分都可以分别 $dp$ 除了 $N$ 的中间部分比较恶心以外其他都还好,自己推一下然后就知道转移,就 $N$ ...
- P1399 [NOI2013]快餐店
传送门 基环树的题当然先考虑树上怎么搞,直接求个直径就完事了 现在多了个环,先把非环上的直径(设为 $ans$)和环上节点 $x$ 到叶子的最大距离(设为 $dis[x]$)求出来 考虑到对于某种最优 ...
- 自动内存管理机制之java内存区域与内存溢出异常
一.运行时数据区域 java虚拟机所管理的内存会包括下面的几个部分: 1.程序计数器:是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器.一般情况下,字节码解释器工作的时候就是通过改变 ...
- String,StringBuilder和StringBuffer
String 字符串常量,由String创建的字符内容,长度是不可改变,存放字符的数组被声明为final. 实际上String类操作字符串是通过建立一个StringBuffer,然后调用append( ...
- 主流NoSQL数据库的分析与选择
一因为新的数据项目的数据量级较大,因此考虑将mysql替换更高性能的数据库. 介绍一下NoSQL(不仅仅是关系型数据库)的不同种类和其擅长的业务. NoSQL的一个比较明显的特点是适用于现代大数据的存 ...
- 集合操作符 Union / Union All / Intersect / Minus
集合操作符 Union / UnionAll / Intersect / Minus -- 生成测试数据 create table dept_01 as select * from dept wher ...
- 多层for循环嵌套,如何能优化一点点,从运行时间维度
将循环次数多的放在最内层,循环次数最少的放在最外层 换句话说,按照循环次数从小到大依次嵌套
- xDSL相关
----------------------- --------------
- conda Pyhon版本切换
1.首先确保你的系统里已经安装了Conda,打开命令行窗口,执行命令:conda --version 2.查看你的系统当前已有的Python环境,执行命令:conda info --envs,从图中我 ...