[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.这其中 ...
随机推荐
- [洛谷P4183][USACO18JAN]Cow at Large P
题目链接 Bzoj崩了之后在洛谷偶然找到的点分好题! 在暴力的角度来说,如果我们$O(n)$枚举根节点,有没有办法在$O(n)$的时间内找到答案呢? 此时如果用树形$dp$的想法,发现是可做的,因为可 ...
- php Excel 导入
php Excel 导入 public function storeSql() { $file = input('file.excel'); $path = ROOT_PATH . 'public' ...
- day 03 int bool str (索引,切片) for 循环
基础数类型总览 10203 123 3340 int +- * / 等等 '今天吃了没?' str 存储少量的数据,+ *int 切片, 其他操作方法 True False bool 判断真假 [12 ...
- 缓存---LRU算法实现
2.LRU 以下是基于双向链表+HashMap的LRU算法实现,对算法的解释如下: 设置一个map存放对应的键和值,同时设置一个双向链表,来保存最近最久未使用的关系,如果访问一个键,键存在于m ...
- vue项目中引入循环执行setInterval或者requestAnimationFrame的用法等
项目中循环计时处理某些方法的情况还是比较常见的,一般会用setInterval来处理,但是这个方法会似的页面卡顿等使用体验不好. 所以就使用浏览器提供的requestAnimationFrame方法, ...
- solve update pip 10.0.0
The bug is found in pip 10.0.0. In linux you need to modify file: /usr/bin/pip from: from pip import ...
- git如何忽略特殊文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定 ...
- 字符串的 Base64 加密和解密
base64加密: FORM encode_base64 USING p_business “字符串string CHANGING p_base64. DATA l_xstring TYPE xstr ...
- php通过反射方法调用私有方法
PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...
- mongoose 开源http库(2) --HTTP服务示例
要创建HTTP服务器,请按照以下格式: 通过调用mg_bind()或mg_bind_opt()创建侦听连接 调用mg_set_protocol_http_websocket()创建listening连 ...