前言

很久没有写关于设计模式的博客了,实在是没有太多的精力去写。但个人觉得设计模式在我们的日常开发中还是挺重要的,它提高了软件的可维护性。因此还是有必要坚持学习设计模式,写博客主要是为了加深我对设计模式的理解。今天我要讲的设计模式是装饰者模式(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的更多相关文章

  1. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  2. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  3. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  4. [转]Design Pattern Interview Questions - Part 2

    Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...

  5. [转]Design Pattern Interview Questions - Part 3

    State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...

  6. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  7. design pattern

    1. visitor design pattern http://butunclebob.com/ArticleS.UncleBob.IuseVisitor

  8. Design Pattern: Observer Pattern

    1. Brief 一直对Observer Pattern和Pub/Sub Pattern有所混淆,下面打算通过这两篇Blog来梳理这两种模式.若有纰漏请大家指正. 2. Use Case 首先我们来面 ...

  9. Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern

    Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming.这其中 ...

随机推荐

  1. 【6.18校内test】T2分数线划定

    分数线划定[题目链接] 这道题也不是什么难题,思路一带而过吧: SOLUTION: First.输入n,m,计算m*1.5的值,接着输入编号和成绩,然后我的做法是在输入编号成绩之后,开一个101大小的 ...

  2. 问题:C++类的静态成员变量如何初始化

    C++类的静态成员变量属于该类,在该类所有的对象间共享. 要弄清如何初始化,首先要明白声明.定义.初始化三个概念的不同. 声明:指定变量的名字和类型,可以多次声明. 定义:为该成员变量分配存储空间,有 ...

  3. P4962 朋也与光玉题解

    题目链接 光坂小镇是一个由 n 个点(编号为 1 ~ n),m 条有向边构成的图,每个节点上都有一个光玉,光玉共有 k 种,编号为 0 ~ k−1. 为了使一切改变,朋也需要找齐全部的 k种光玉.他可 ...

  4. django1.9安装以及使用

    安装setuptoolswget --no-check-certificate https://pypi.python.org/packages/69/56/f0f52281b5175e3d9ca86 ...

  5. form表单提交被拦截

    最近做的一个项目,利用form表单(可以避免跨域问题)提交,在chrome可以正常进行跳转,但是在手机端,以及一些pc端浏览器却无法正常跳转.通过检查后台日志,没有正常跳转的都是因为后天直接没有收到该 ...

  6. orm的设计思路

    一,我们先搞懂什么是orm? ORM:对象关系映射(Object Relational Mapping,简称ORM),目的是想像操作对象一样操作数据库.因为数据库不是面向对象的,所以需要编程进行映射. ...

  7. centos部署LVS负载均衡直接路由DR模式

    环境: 在vm里开三个虚拟机 负载调度器:10.0.3.102 真实服务器1:10.0.3.103 真实服务器2:10.0.3.104 虚拟ip: 10.0.3.99 (用来飘移) 负载调度器上 if ...

  8. java复习(3)继承下

    一.抽象类 ------------------------------------- 1.抽象定义概述:抽象类时从多个事物中奖共性的,本质的内容抽取出来 例如:狼和狗共性都是犬科,犬科就是抽象出来的 ...

  9. AIX中的服务管理

    1.SRC AIX系统使用资源控制器(SRC,system   resource  controller),控制各种服务子系统,包括启动,停止进程,搜集进程状态信息等.   AIX系统中服务有子系统组 ...

  10. PAT Basic 1043 输出PATest (20 分)

    给定一个长度不超过 ​ ​​ 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符 ...