面向对象开发技术课件-设计模式
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
的时候无需修改客户端,也就是说,它在
某种程度上支持“开-闭”原则。
这个模式的缺点是对“开-闭”原则的支持
不够,因为如果有新的产品加入到系统中
去,就需要修改工厂类,将必要的逻辑加
入到工厂类中。工厂方法模式的引进
6/23/2023
24
工厂方法模式
工厂方法模式是简单工厂模式的进一
步抽象和推广。由于使用了多态性,
不妨把抽象工厂类合并到具体的工厂
类中去。由于反正只有一个具体工厂
类,所以不妨将工厂方法改成为静态
方法,这时候就得到了简单工厂模式。
6/23/2023
37
观察
与简单工厂模式中的情形一样的是,
ConcreteCreator 的factory() 方法返还
的数据类型是一个抽象类型Product,而不
所以解决方案并不描述一个特定而具
体的设计或实现,而是提供设计问题
的抽象描述和怎样用一个具有一般意
义的元素组合(类或对象组合)来解
决这个问题。
6/23/2023
6
设计模式要素
4. 效果(consequences) 描述了模式应用
的效果及使用模式应权衡的问题。尽管我
们描述设计决策时,并不总提到模式效果,
用ConcreteCreator1 对象的工厂方法
factory(),接着后者调用
ConcreteProduct1 的构造子创建出产
品对象。如下面的时序图所示。
6/23/2023
34
工厂方法模式的活动序列图
6/23/2023
35
比较
工厂方法模式和简单工厂模式在结构
上的不同是很明显的。工厂方法模式
序的调用以创建产品对象。
在本系统中给出了两个这样的角色,
也就是具体Java 类ConcreteCreator1
和ConcreteCreator2。
6/23/2023
31
结构与角色
抽象产品(Product)角色:工厂方法
模式所创建的对象的超类型,也就是
产品对象的共同父类或共同拥有的接
口。在本系统中,这个角色由接口
oncreteProduct2 扮演,它们都实现
了接口Product。
6/23/2023
33
工厂方法模式的活动序列图
Client 对象的活动可以分成两部分。
(1)客户端创建ConcreteCreator1
对象。这时客户端所持有变量的静态
类型是Creator,而实际类型是
ConcreteCreator1。然后,客户端调
的设计问题,如怎样用对象表示算法
等。也可能描述了导致不灵活设计的
类或对象结构。有时候,问题部分会
包括使用模式必须满足的一系列先决
条件。
6/23/2023
5
设计模式要素
3. 解决方案(solution) 描述了设计
的组成成分,它们之间的相互关系及
各自的职责和协作方式。因为模式就
像一个模板,可应用于多种不同场合,
void grow();
void harvest();
void plant();} Nhomakorabea6/23/2023
13
public class Apple implements FruitIF
{
public void grow()
{
log("Apple is growing..."); }
public void harvest()
你就能一次又一次地使用该方案
而不必做重复劳动”
2
面向对象设计模式
6/23/2023
在面向对象的编程中使用模式化
方法研究的开创性著作,是Design
Patterns - Elements of
Reusable Object-Oriented
Software, E.Gamma, R. Helm, R.
模式
6/23/2023
模式就是对以解决问题的记录,
使处理后面与之类似的问题时更
容易。
设计模式使人们更加简单方便地
复用成功的设计和体系结构。
1
模式
6/23/2023
hristopher Alexander 说过:
“每一个模式描述了一个在我们
周围不断重复发生的问题,以及
该问题的解决方案的核心。这样,
{
log("Apple has been harvested."); }
public void plant()
{
log("Apple has been planted."); }
public static void log(String msg)
{
System.out.println(msg); }
是哪一个具体产品类型,而客户端也不必
知道所得到的产品的真实类型。这种多态
性设计将工厂类选择创建哪一个产品对象、
如何创建这个对象的细节完全封装在具体
工厂类内部。
工厂方法模式之所以有一个别名叫多态性
的核心是一个抽象工厂类,而简单工
厂模式把核心放在一个具体类上。工
厂方法模式可以允许很多具体工厂类
从抽象工厂类中将创建行为继承下来,
从而可以成为多个简单工厂模式的综
合,进而推广了简单工厂模式。
6/23/2023
36
比较
工厂方法模式退化后可以变得很像简
单工厂模式。设想如果非常确定一个
系统只需要一个具体工厂类,那么就
类需要判断在什么时候创建某种产品。
这种对时机的判断和对哪一种具体产
品的判断逻辑混合在一起,使得系统
在将来进行功能扩展时较为困难。
6/23/2023
20
观察
功能的扩展体现在引进新的产品上。
“开–闭”原则要求系统允许当新的
产品加入系统中,而无需对现有代码
进行修改。
这一点对于产品的消费角色是成立的,
public int getTreeAge() { return treeAge; }
public void setTreeAge(int treeAge){
this.treeAge = treeAge; }
private int treeAge;
}
6/23/2023
14
public class FruitGardener
6/23/2023
16
简单工厂模式
简单工厂模式是有一个工厂类根据传
入的参量决定创建出哪一种产品类的
实例。
6/23/2023
17
角色与结构
工厂类(Creator)角色:该角色是工厂方法模
式的核心,含有与应用紧密相关的商业逻辑。工
厂类在客户端的直接调用下创建产品对象,它往
往由一个具体类实现。
抽象产品(Product)角色:担任这个角色的类
创建哪一个产品类的实例。
而客户端则可以免除直接创建产品对
象的责任,而仅仅负责“消费”产品。
简单工厂模式通过这种做法实现了对
责任的分割。
6/23/2023
19
模式的缺点
工厂类集中了所有的产品创建逻辑,
形成一个无所不知的全能类,有人把
这种类叫做上帝类(God Class)
当产品类有不同的接口种类时,工厂
{ return new Strawberry(); }
else if (which.equalsIgnoreCase("grape"))
{ return new Grape(); }
else
{
throw new BadFruitException("Bad fruit request");
} } }
建对象的工厂类必须实现这个接口。
在上面的系统中这个角色由接口
Creator 扮演;在实际的系统中,这
个角色也常常使用抽象类实现。
6/23/2023
30
结构与角色
具体工厂(Concrete Creator)角色:
担任这个角色的是实现了抽象工厂接
口的具体类。具体工厂角色含有与应
用密切相关的逻辑,并且受到应用程
是工厂方法模式所创建的对象的父类,或它们共
同拥有的接口。抽象产品角色可以用接口或者抽
象类实现。
具体产品(Concrete Product)角色:工厂方法
模式所创建的任何对象都是这个角色的实例,具
6/23/2023
18
体产品角色由一个具体类实现。
模式优点
模式的核心是工厂类。这个类含有必
要的判断逻辑,可以决定在什么时候
但它们对于评价设计选择和理解使用模式
的代价及好处具有重要意义。软件效果大
多关注对时间和空间的衡量,它们也表述
了语言和实现问题。因为复用是面向对象
设计的要素之一,所以模式效果包括它对
系统的灵活性、扩充性或可移植性的影响,
显式地列出这些效果对理解和评价这些模
式很有帮助。
6/23/2023
7
设计模式
创建型:对象创建
结构型:处理类或对象组合
行为型:对类或对象怎样交互和怎样
分配职责进行描述
6/23/2023
8
简单工厂模式(封装可变性)
简单工厂模式是类的创建模式
抽象产品
工厂
6/23/2023
创建
具体产品
9
6/23/2023
10
6/23/2023
11
例子
6/23/2023
12
public interface FruitIF {
词汇表,我们自己以及同事之间就可以讨
论模式并在编写文档时使用它们。模式名
可以帮助我们思考,便于我们与其他人交
流设计思想及设计结果。找到恰当的模式
名也是我们设计模式编目工作的难点之一
6/23/2023
4
设计模式要素
2. 问题(problem) 描述了应该在何时
使用模式。它解释了设计问题和问题
存在的前因后果,它可能描述了特定
过程。工厂角色必须知道每一种产品,如何创建
它们,以及何时向客户端提供它们。换言之,接
纳新的产品意味着修改这个工厂角色的源代码。
简单工厂角色只在有限的程度上支持“开–闭”
6/23/2023
22
工厂方法模式
工厂方法模式是类的创建模式,又叫
做虚拟构造子(Virtual Constructor)
模式或者多态性工厂(Polymorphic
Product 扮演;在实际的系统中,这
个角色也常常使用抽象类实现。
6/23/2023
32
结构与角色
具体产品(Concrete Product)角色:
这个角色实现了抽象产品角色所声明
的接口。工厂方法模式所创建的每一
个对象都是某个具体产品角色的实例。
在本系统中,这个角色由具体类
CocnreteProduct1 和
Factory)模式。
工厂方法模式的用意是定义一个创建
产品对象的工厂接口,将实际创建工
作推迟到子类中。
6/23/2023
23
简单工厂模式的优缺点
在简单工厂模式中,一个工厂类处于对产
品类实例化的中心位置上,它知道每一个
产品,它决定哪一个产品类应当被实例化。
这个模式的优点是允许客户端相对独立于
产品创建的过程,并且在系统引入新产品
这种进一步抽象化的结果,使这种工厂方
法模式可以用来允许系统在不修改具体工
厂角色的情况下引进新的产品
6/23/2023
26
6/23/2023
27
工厂方法模式的结构
6/23/2023
28
6/23/2023
29
结构与角色
抽象工厂(Creator)角色:担任这个
角色的是工厂方法模式的核心,它是
与应用程序无关的。任何在模式中创
Johnson, and J.
Vlissides,1995, AddisonWesley.
3
设计模式要素
1. 模式名称(pattern name) 一个助记
名,它用一两个词来描述模式的问题、解
决方案和效果。命名一个新的模式增加了
我们的设计词汇。设计模式允许我们在较
高的抽象层次上进行设计。基于一个模式
6/23/2023
15
在使用时,只须调用FruitGardener的
factory()方法即可
FruitGardener gardener = new
FruitGardener();
gardener.factory("grape");
gardener.factory("apple");
gardener.factory("strawberry");
工厂方法模式保持了简单工厂模式的
优点,而且克服了它的缺点。
6/23/2023
25
工厂方法模式
在工厂方法模式中,核心的工厂类不再负
责所有的产品的创建,而是将具体创建的
工作交给子类去做。这个核心类则摇身一
变,成为了一个抽象工厂角色,仅负责给
出具体工厂子类必须实现的接口,而不接
触哪一个产品类应当被实例化这种细节。
{
public FruitIF factory(String which) throws
BadFruitException
{
if (which.equalsIgnoreCase("apple"))
{ return new Apple(); }
else if (which.equalsIgnoreCase("strawberry"))
而对于工厂角色是不成立的。
6/23/2023
21
观察
对于产品消费角色来说,任何时候需要某种产品,
只需向工厂角色请求即可。而工厂角色在接到请
求后,会自行判断创建和提供哪一个产品。所以,
产品消费角色无需知道它得到的是哪一个产品;
换言之,产品消费角色无需修改就可以接纳新的
产品。
对于工厂角色来说,增加新的产品是一个痛苦的
某种程度上支持“开-闭”原则。
这个模式的缺点是对“开-闭”原则的支持
不够,因为如果有新的产品加入到系统中
去,就需要修改工厂类,将必要的逻辑加
入到工厂类中。工厂方法模式的引进
6/23/2023
24
工厂方法模式
工厂方法模式是简单工厂模式的进一
步抽象和推广。由于使用了多态性,
不妨把抽象工厂类合并到具体的工厂
类中去。由于反正只有一个具体工厂
类,所以不妨将工厂方法改成为静态
方法,这时候就得到了简单工厂模式。
6/23/2023
37
观察
与简单工厂模式中的情形一样的是,
ConcreteCreator 的factory() 方法返还
的数据类型是一个抽象类型Product,而不
所以解决方案并不描述一个特定而具
体的设计或实现,而是提供设计问题
的抽象描述和怎样用一个具有一般意
义的元素组合(类或对象组合)来解
决这个问题。
6/23/2023
6
设计模式要素
4. 效果(consequences) 描述了模式应用
的效果及使用模式应权衡的问题。尽管我
们描述设计决策时,并不总提到模式效果,
用ConcreteCreator1 对象的工厂方法
factory(),接着后者调用
ConcreteProduct1 的构造子创建出产
品对象。如下面的时序图所示。
6/23/2023
34
工厂方法模式的活动序列图
6/23/2023
35
比较
工厂方法模式和简单工厂模式在结构
上的不同是很明显的。工厂方法模式
序的调用以创建产品对象。
在本系统中给出了两个这样的角色,
也就是具体Java 类ConcreteCreator1
和ConcreteCreator2。
6/23/2023
31
结构与角色
抽象产品(Product)角色:工厂方法
模式所创建的对象的超类型,也就是
产品对象的共同父类或共同拥有的接
口。在本系统中,这个角色由接口
oncreteProduct2 扮演,它们都实现
了接口Product。
6/23/2023
33
工厂方法模式的活动序列图
Client 对象的活动可以分成两部分。
(1)客户端创建ConcreteCreator1
对象。这时客户端所持有变量的静态
类型是Creator,而实际类型是
ConcreteCreator1。然后,客户端调
的设计问题,如怎样用对象表示算法
等。也可能描述了导致不灵活设计的
类或对象结构。有时候,问题部分会
包括使用模式必须满足的一系列先决
条件。
6/23/2023
5
设计模式要素
3. 解决方案(solution) 描述了设计
的组成成分,它们之间的相互关系及
各自的职责和协作方式。因为模式就
像一个模板,可应用于多种不同场合,
void grow();
void harvest();
void plant();} Nhomakorabea6/23/2023
13
public class Apple implements FruitIF
{
public void grow()
{
log("Apple is growing..."); }
public void harvest()
你就能一次又一次地使用该方案
而不必做重复劳动”
2
面向对象设计模式
6/23/2023
在面向对象的编程中使用模式化
方法研究的开创性著作,是Design
Patterns - Elements of
Reusable Object-Oriented
Software, E.Gamma, R. Helm, R.
模式
6/23/2023
模式就是对以解决问题的记录,
使处理后面与之类似的问题时更
容易。
设计模式使人们更加简单方便地
复用成功的设计和体系结构。
1
模式
6/23/2023
hristopher Alexander 说过:
“每一个模式描述了一个在我们
周围不断重复发生的问题,以及
该问题的解决方案的核心。这样,
{
log("Apple has been harvested."); }
public void plant()
{
log("Apple has been planted."); }
public static void log(String msg)
{
System.out.println(msg); }
是哪一个具体产品类型,而客户端也不必
知道所得到的产品的真实类型。这种多态
性设计将工厂类选择创建哪一个产品对象、
如何创建这个对象的细节完全封装在具体
工厂类内部。
工厂方法模式之所以有一个别名叫多态性
的核心是一个抽象工厂类,而简单工
厂模式把核心放在一个具体类上。工
厂方法模式可以允许很多具体工厂类
从抽象工厂类中将创建行为继承下来,
从而可以成为多个简单工厂模式的综
合,进而推广了简单工厂模式。
6/23/2023
36
比较
工厂方法模式退化后可以变得很像简
单工厂模式。设想如果非常确定一个
系统只需要一个具体工厂类,那么就
类需要判断在什么时候创建某种产品。
这种对时机的判断和对哪一种具体产
品的判断逻辑混合在一起,使得系统
在将来进行功能扩展时较为困难。
6/23/2023
20
观察
功能的扩展体现在引进新的产品上。
“开–闭”原则要求系统允许当新的
产品加入系统中,而无需对现有代码
进行修改。
这一点对于产品的消费角色是成立的,
public int getTreeAge() { return treeAge; }
public void setTreeAge(int treeAge){
this.treeAge = treeAge; }
private int treeAge;
}
6/23/2023
14
public class FruitGardener
6/23/2023
16
简单工厂模式
简单工厂模式是有一个工厂类根据传
入的参量决定创建出哪一种产品类的
实例。
6/23/2023
17
角色与结构
工厂类(Creator)角色:该角色是工厂方法模
式的核心,含有与应用紧密相关的商业逻辑。工
厂类在客户端的直接调用下创建产品对象,它往
往由一个具体类实现。
抽象产品(Product)角色:担任这个角色的类
创建哪一个产品类的实例。
而客户端则可以免除直接创建产品对
象的责任,而仅仅负责“消费”产品。
简单工厂模式通过这种做法实现了对
责任的分割。
6/23/2023
19
模式的缺点
工厂类集中了所有的产品创建逻辑,
形成一个无所不知的全能类,有人把
这种类叫做上帝类(God Class)
当产品类有不同的接口种类时,工厂
{ return new Strawberry(); }
else if (which.equalsIgnoreCase("grape"))
{ return new Grape(); }
else
{
throw new BadFruitException("Bad fruit request");
} } }
建对象的工厂类必须实现这个接口。
在上面的系统中这个角色由接口
Creator 扮演;在实际的系统中,这
个角色也常常使用抽象类实现。
6/23/2023
30
结构与角色
具体工厂(Concrete Creator)角色:
担任这个角色的是实现了抽象工厂接
口的具体类。具体工厂角色含有与应
用密切相关的逻辑,并且受到应用程
是工厂方法模式所创建的对象的父类,或它们共
同拥有的接口。抽象产品角色可以用接口或者抽
象类实现。
具体产品(Concrete Product)角色:工厂方法
模式所创建的任何对象都是这个角色的实例,具
6/23/2023
18
体产品角色由一个具体类实现。
模式优点
模式的核心是工厂类。这个类含有必
要的判断逻辑,可以决定在什么时候
但它们对于评价设计选择和理解使用模式
的代价及好处具有重要意义。软件效果大
多关注对时间和空间的衡量,它们也表述
了语言和实现问题。因为复用是面向对象
设计的要素之一,所以模式效果包括它对
系统的灵活性、扩充性或可移植性的影响,
显式地列出这些效果对理解和评价这些模
式很有帮助。
6/23/2023
7
设计模式
创建型:对象创建
结构型:处理类或对象组合
行为型:对类或对象怎样交互和怎样
分配职责进行描述
6/23/2023
8
简单工厂模式(封装可变性)
简单工厂模式是类的创建模式
抽象产品
工厂
6/23/2023
创建
具体产品
9
6/23/2023
10
6/23/2023
11
例子
6/23/2023
12
public interface FruitIF {
词汇表,我们自己以及同事之间就可以讨
论模式并在编写文档时使用它们。模式名
可以帮助我们思考,便于我们与其他人交
流设计思想及设计结果。找到恰当的模式
名也是我们设计模式编目工作的难点之一
6/23/2023
4
设计模式要素
2. 问题(problem) 描述了应该在何时
使用模式。它解释了设计问题和问题
存在的前因后果,它可能描述了特定
过程。工厂角色必须知道每一种产品,如何创建
它们,以及何时向客户端提供它们。换言之,接
纳新的产品意味着修改这个工厂角色的源代码。
简单工厂角色只在有限的程度上支持“开–闭”
6/23/2023
22
工厂方法模式
工厂方法模式是类的创建模式,又叫
做虚拟构造子(Virtual Constructor)
模式或者多态性工厂(Polymorphic
Product 扮演;在实际的系统中,这
个角色也常常使用抽象类实现。
6/23/2023
32
结构与角色
具体产品(Concrete Product)角色:
这个角色实现了抽象产品角色所声明
的接口。工厂方法模式所创建的每一
个对象都是某个具体产品角色的实例。
在本系统中,这个角色由具体类
CocnreteProduct1 和
Factory)模式。
工厂方法模式的用意是定义一个创建
产品对象的工厂接口,将实际创建工
作推迟到子类中。
6/23/2023
23
简单工厂模式的优缺点
在简单工厂模式中,一个工厂类处于对产
品类实例化的中心位置上,它知道每一个
产品,它决定哪一个产品类应当被实例化。
这个模式的优点是允许客户端相对独立于
产品创建的过程,并且在系统引入新产品
这种进一步抽象化的结果,使这种工厂方
法模式可以用来允许系统在不修改具体工
厂角色的情况下引进新的产品
6/23/2023
26
6/23/2023
27
工厂方法模式的结构
6/23/2023
28
6/23/2023
29
结构与角色
抽象工厂(Creator)角色:担任这个
角色的是工厂方法模式的核心,它是
与应用程序无关的。任何在模式中创
Johnson, and J.
Vlissides,1995, AddisonWesley.
3
设计模式要素
1. 模式名称(pattern name) 一个助记
名,它用一两个词来描述模式的问题、解
决方案和效果。命名一个新的模式增加了
我们的设计词汇。设计模式允许我们在较
高的抽象层次上进行设计。基于一个模式
6/23/2023
15
在使用时,只须调用FruitGardener的
factory()方法即可
FruitGardener gardener = new
FruitGardener();
gardener.factory("grape");
gardener.factory("apple");
gardener.factory("strawberry");
工厂方法模式保持了简单工厂模式的
优点,而且克服了它的缺点。
6/23/2023
25
工厂方法模式
在工厂方法模式中,核心的工厂类不再负
责所有的产品的创建,而是将具体创建的
工作交给子类去做。这个核心类则摇身一
变,成为了一个抽象工厂角色,仅负责给
出具体工厂子类必须实现的接口,而不接
触哪一个产品类应当被实例化这种细节。
{
public FruitIF factory(String which) throws
BadFruitException
{
if (which.equalsIgnoreCase("apple"))
{ return new Apple(); }
else if (which.equalsIgnoreCase("strawberry"))
而对于工厂角色是不成立的。
6/23/2023
21
观察
对于产品消费角色来说,任何时候需要某种产品,
只需向工厂角色请求即可。而工厂角色在接到请
求后,会自行判断创建和提供哪一个产品。所以,
产品消费角色无需知道它得到的是哪一个产品;
换言之,产品消费角色无需修改就可以接纳新的
产品。
对于工厂角色来说,增加新的产品是一个痛苦的