第八章 装饰者模式 欢迎饮用星巴兹(Starbuzz)咖啡 最初设计的订购系统(下页):.

Slides:



Advertisements
Similar presentations
主要内容 Java 的常用包 Java 的常用包 “ == ” 和 “ equals ” 的用法 “ == ” 和 “ equals ” 的用法 基本数据类型与引用类型 基本数据类型与引用类型 String 和 StringBuffer String 和 StringBuffer 对象的克隆( clone.
Advertisements

软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
Java 程序分类 Java Application :是完整程序,需要独立的解 释器解释运行;以 “.java” 为后缀的文件,以 main() 方法作为程序入口,由 java 编译器编译生 成字节码,由 Java 解释器加载执行字节码。 Java Applet 没有 main() 方法作为程序入口,是嵌在.
面向对象程序设计 、. 第二章 面向对象的分析与设计 学习目标 1 确定系统中的对象 2 确定对象的属性及操作 3 测试对象的有效性 4 区分对象和类 5 了解面向对象的编程和过程化编程之间的区别 6 了解封装的主要好处 7 了解软件开发的主要步骤.
第四章 类、对象和接口.
第三讲 面向对象(上).
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
项目6 通用堆栈.
Java程序设计教程 第一讲 Java概述.
紅茶半糖去冰.
Java的程式架構與基本觀念 Java語言的歷史 Java程式的開發環境 Java程式的架構 輸出與輸入物件之使用 工具使用方法介紹
四資二甲 第三週作業 物件導向程式設計.
面向对象的程序设计(一).
第一章 面向对象程序设计.
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
氣候變遷對南台灣降雨造成之影響 研究背景 結果與討論 研究方法 結論 朱振豪1 、彭康豪1 、莊煌甲1 、邱俊彥2,* 研究目的
第二章 JAVA语言基础.
Ch07 介面與多重繼承 物件導向程式設計(II).
第10讲 Java面向对象编程基础(4) 教学目标 主要内容.
第三章 控制结构.
Ch08 巢狀類別 物件導向程式設計(II).
程式設計實作.
第5章 异常处理 王德俊 上海交通大学继续教育学院.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
第四章 在 C# 中实现 OOP 概念.
我的喜好 玉桂狗 5D班(吳夢殷).
Java基础 JavaSE异常.
程序與函數的類別方法 目的:模組化程式設計 方法:由上而下設計 注意事項:(1)獨立性 (2)結合問題 (3)子問題間的溝通.
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
程式設計實作.
CH09 套件 物件導向程式設計(II).
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
第9章 多线程 王德俊 上海交通大学继续教育学院.
面向对象程序设计 、.
Java程序设计 第9章 继承和多态.
辅导课程六.
C#面向对象程序设计 $7 继承和多态性.
中国矿大计算机学院杨东平 第5章 接口和包 中国矿大计算机学院杨东平
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
Object-Oriented Programming (Java)
第9讲 Java的继承与多态(一) 类的继承 子类的创建 方法覆盖.
异常及处理.
第一章 Java语言概述.
C/C++/Java 哪些值不是头等程序对象
* 單元:電腦與問題解決 主題:Java物件導向程式設計-類別與物件 台南縣國立善化高中 蕭嘉民 老師
简单工厂模式.
辅导课程八.
JAVA 编 程 技 术 主编 贾振华 2010年1月.
第二章Java基本程序设计.
第二章 Java基本语法 讲师:复凡.
$9 泛型基础.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
第二章 Java语法基础.
第二章 Java基本语法 讲师:复凡.
Chapter 18 使用GRASP的对象设计示例.
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
辅导课程十五.
第二章 Java基本语法 讲师:复凡.
第6單元 6-1 類別的繼承 (Class Inheritance) 6-2 抽象類別 (Abstract Class)
辅导课程十二.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
判斷(選擇性敘述) if if else else if 條件運算子.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
第二章 Java基础语法 北京传智播客教育
輸出執行結果到螢幕上 如果要將執行結果的文字和數值都「輸出」到電腦螢幕時,程式要怎麼寫? class 類別名稱 {
第二章 Java基本语法 讲师:复凡.
第6章 继承和多态 伍孝金
Summary
Presentation transcript:

第八章 装饰者模式 欢迎饮用星巴兹(Starbuzz)咖啡 最初设计的订购系统(下页):

家庭混合咖啡 焦炒咖啡 无咖啡因咖啡 蒸馏咖啡

购买咖啡时,每一种咖啡中能添加一种或几种调料:steamed milk(蒸煮的牛奶), soy(酱油), mocha(摩卡,也称 为巧克力),和 whipped milk (加了甜点心的牛奶)。每一种调料都要收一点钱,星巴兹(Starbuzz)咖啡订购系统变成下面的样子(下页):

每个cost()方法计算咖啡及各种调料的价钱。 类爆炸! 每个cost()方法计算咖啡及各种调料的价钱。 从基类派生添加了各种调料的咖啡子类。

修改后的订购系统

修改后的订购系统怎么样?

这个设计的缺陷 如果调料的价格改变,我们需要修改现存的代码。 如果增加了新的调料,我们需要在基类增加新的方 法以及修改cost()方法。 我们也可能有新的饮料类型。一些饮料类型,例如, 冰茶(ice tea),现有的调料可能是不合适的。但是, 茶子类仍然后继承基类的调料方法。 如果客户需要双份mocha,怎么办呢?

开闭原则 我们的目的是允许类易于扩展,组合新的行为, 但不修改现有的代码。

会会装饰者模式 我们已经看到:附加调料的饮料定价模式,用继承表示是不合适的;在基类增加调料的实例变量和方法,对一些子类也是不合适的。 这里,我们试试:以饮料为主体,用调料“装饰”饮料。例如,如果客户需要Dark Roast(焦炒咖啡) ,添加Mocha(摩卡)和Whip(甜点心)。

会会装饰者模式(续) 我们可以: ① 取DarkRoast (焦炒咖啡)对象; 用Mocha (摩卡)对象装饰它; 用Whip (甜点心)对象装饰它; 调用cost()方法计算价格,总价格的计算需要委托。 但是,我们怎样装饰一个对象?又怎样委托?

用装饰者构造饮料订购系统 ① 从DarkRoast (焦炒咖啡)对象开始

客户需要Mocha (摩卡) ,所以,我们创建一个Mocha 对象,并用它包装DarkRoast (焦炒咖啡) 。 装饰者对象是“包装者”。

客户也需要Whip (甜点心) ,所以,我们也创建一个 Whip装饰者,并用它包装Mocha (摩卡) 。

现在为客户计算价格。我们调用最外层装饰者(Whip 甜点心)的cost()。Whip委托它所装饰的对象计算价格。 它获得了价格后,再累加Whip的价格。

目前做的… 装饰者和被装饰对象有相同的超类型; 可以用一个或多个装饰者包装一个对象; 任何时候需要原始对象(即被包装的对象),都可以用装 饰过的对象代替它。因为装饰者和被装饰者有相同的 超类型; 装饰者可以在所委托的被装饰者的行为之前与/或之后, 加上自己的行为,以达到特定的目的。 对象可以在任何时候被装饰,所以可以在运行时动态 地、不限量地使用装饰者来装饰对象。

装饰者模式定义

装饰者模式类图

装饰我们 的饮料

写星巴兹(Strbuzz)代码 我们从Beverage类开始,它与原设计是一样的: public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost();

实现调料(装饰者)抽象类 public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }

对饮料编码 public class Espresso extends Beverage { //蒸馏咖啡 public Espresso() { description = "Espresso"; } public double cost() { return 1.99;

对饮料编码(续) public class HouseBlend extends Beverage { //家庭混合咖啡 public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89;

实现调料(装饰者)具体类 public class Mocha extends CondimentDecorator { // 摩卡 Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; public double cost() { return .20 + beverage.cost(); 描述不只是饮料,还要包括添加的调料。

订购星巴兹(Starbuzz)咖啡的测试代码 public class StarbuzzCoffee { public static void main(String args[]) { Beverage beverage = new Espresso(); // 蒸馏咖啡 System.out.println(beverage.getDescription() + " $" + Beverage.cost()); Beverage beverage2 = new DarkRoast(); // 焦炒咖啡 beverage2 = new Mocha(beverage2); // 添加摩卡 beverage2 = new Whip(beverage2); // 添加甜点心 System.out.println(beverage2.getDescription() + " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend(); // 家庭混合咖啡 beverage3 = new Soy(beverage3); // 添加酱油 beverage3 = new Mocha(beverage3); // 添加摩卡 beverage3 = new Whip(beverage3); // 添加甜点心 System.out.println(beverage3.getDescription() + " $" + beverage3.cost()); }

订购结果

真实世界的装饰者:Java I/O java.io包内的类太多了!其实,许多类都是装饰者。下面是一个典型的对象集合(下页):

真实世界的 装饰者: Java I/O(续)

Java I/O装饰类