面向对象设计模式1适配器模式
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 问题:系统的数据和行为都正确,但是接 口不符。通常用于必须从抽象类派生时。
• 解决方案:Adapter模式提供了具有所需接 口的包装类。
Adapter模式定义
• 参与者与协作者:Adapter改变了Adaptee的接 口,使Adaptee与Adapter的基类Target匹配。 这样Client就可以使用Adaptee了,好像它是 Target类型。
hasNext() next() remove()
<<interface>> Enumeration
hasMoreElements() nextElement()
实例
• 有一个类(adaptee)实现了数学中的幂次运 算,方法中需要传入两个参数,一个是基 数base,另外一个是幂次exp。现在客户端 需要一个求得一个数的平方的函数接口 (target),传入一个数,得到它的平方值。 为了复用已经存在的类adaptee,适用 Adapter来适配adaptee,adapter实现了 target接口。
Iterator
hasNext() next() remove()
被适配者接口
<<interface>> Enumeration
hasMoreElements() nextElement()
<<interface>> Iterator
hasNext() next() remove()
EnumerationIterator
– displayIt – fillIt – undisplayIt
• 不能直接使用XXCircle,因为想保持 Shape类的多态行为
– 名称和参数列表与Shape类不同 – 无法从Shape类派生
• Circle包含一个XXCircle
Shape
+setLocation() +getLocation() +display() +fill() +setColor() +undisplay()
现有系统
适配器
厂商类
例子
• 需求
– 有一个Shape类, 和几个派生类
– 要求实现一个新的 Shape——圆 (Circle)
Point
Shape
+setLocation() +getLocation() +display() +fill() +setColor() +undisplay()
Line
}
• 客户使用适配器的过程如下:
– 客户通过目标接口调用适配器的方法对适配器 发出请求
– 适配器使用被适配者接口把请求转换成被适配 者的一个或多个调用接口
– 客户收到调用的结果,但并未察觉这一切是适 配器在起转换作用
Adapter模式定义
• 定义:将一个类的接口,转换成客户期望 的另一个接口。
• 意图:使控制范围之外的一个原有对象与 某个接口匹配
Point
Line
+display() +fill() +undisplay()
+display() +fill() +undisplay()
Square
+display() +fill() +undisplay()
Circle
+display() +fill() +undisplay()
XXCircle
Adaptee +specificRequest()
Adapter +request()
练习பைடு நூலகம்
• 试着将Shape类,Circle类, XXCircle类 对应到对象适配器/类适配器模式的定义中
真实世界中的适配器
• 想一想Java语言中不同版本中有没有需要 进行适配的
真实世界中的适配器
• 早期java版本中集合(Collection)类型 (例如:Vector,Stack,Hashtable)都实现 了一个elements()方法。该方法返回一个 Enumeration(枚举)
• 新版本中开始使用Iterator(迭代器)接口, 这个接口和枚举接口很像,但不同的是, 迭代器还提供了删除元素的能力。
问题
• 面对遗留代码,这些代码会暴露出枚举器 接口,但我们又希望在新的代码中只使用 迭代器。
• 解决办法
– 构造一个适配器 – 将枚举适配到迭代器
<<interface>>
目标接口
Square
+display() +display()
+fill()
+fill()
+undisplay() +undisplay()
+display() +fill() +undisplay()
• 优秀的编程人员首先会四处寻找替代方案 • 发现有人已经编写好了一个处理圆形的类,
名叫XXCircle • 它并不知道我们的命名规则,而是
在架构层次上的应用
• JDBC驱动软件与适配器模式 • JDBC给出一个客户端通用的界面。每个数据库引擎的JDBC驱动软件
都是一个介于JDBC接口和数据库引擎接口之间的适配器软件 • 抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软
件,即为各个数据库引擎准备的驱动软件。
• JDBC/ODBC桥梁
Adapter模式定义
• 效果:Adapter模式使原有对象能够适应新的类 结构,不受其接口的限制。
• 实现:将原有类包含在另一个类之中。让包含类 与需要的接口匹配,调用被包含类的方法
类的适配器
• 类适配器不是使用组合来适配被适配者,而是继承被适 配者和目标类
Client
Target +request()
– 如果没有合适的JDBC驱动软件,用户也可以通过 ODBC驱动软件把JDBC通过一个JDBC/ODBC桥梁软 件与ODBC驱动软件连接起来,从而达到连接数据库的 目的。
适配器模式
• 适配器现实中到处都是
– 如:中国制造的笔记本电脑带到欧洲使 用,需要一个交流电的适配器
• 面向对象适配器
– 假设有一个软件系统,你希望它能和一 个新的厂商类库搭配使用,但是这个新 厂商所设计出来的接口,不同于旧厂商 的接口
现有系统
厂商类
• 不想改变现有代码 • 也不能改变厂商的代码 • 怎么办?
+displayIt() +fillIt() +undisplayIt()
• 实现Adapter模式
Class Circle extends Shape { private XXCircle myXXCircle; public Circle ( ) { myXXCircle= new XXCircle ( ); } void public display ( ) { myXXCircle.displayIt (); } …
• 解决方案:Adapter模式提供了具有所需接 口的包装类。
Adapter模式定义
• 参与者与协作者:Adapter改变了Adaptee的接 口,使Adaptee与Adapter的基类Target匹配。 这样Client就可以使用Adaptee了,好像它是 Target类型。
hasNext() next() remove()
<<interface>> Enumeration
hasMoreElements() nextElement()
实例
• 有一个类(adaptee)实现了数学中的幂次运 算,方法中需要传入两个参数,一个是基 数base,另外一个是幂次exp。现在客户端 需要一个求得一个数的平方的函数接口 (target),传入一个数,得到它的平方值。 为了复用已经存在的类adaptee,适用 Adapter来适配adaptee,adapter实现了 target接口。
Iterator
hasNext() next() remove()
被适配者接口
<<interface>> Enumeration
hasMoreElements() nextElement()
<<interface>> Iterator
hasNext() next() remove()
EnumerationIterator
– displayIt – fillIt – undisplayIt
• 不能直接使用XXCircle,因为想保持 Shape类的多态行为
– 名称和参数列表与Shape类不同 – 无法从Shape类派生
• Circle包含一个XXCircle
Shape
+setLocation() +getLocation() +display() +fill() +setColor() +undisplay()
现有系统
适配器
厂商类
例子
• 需求
– 有一个Shape类, 和几个派生类
– 要求实现一个新的 Shape——圆 (Circle)
Point
Shape
+setLocation() +getLocation() +display() +fill() +setColor() +undisplay()
Line
}
• 客户使用适配器的过程如下:
– 客户通过目标接口调用适配器的方法对适配器 发出请求
– 适配器使用被适配者接口把请求转换成被适配 者的一个或多个调用接口
– 客户收到调用的结果,但并未察觉这一切是适 配器在起转换作用
Adapter模式定义
• 定义:将一个类的接口,转换成客户期望 的另一个接口。
• 意图:使控制范围之外的一个原有对象与 某个接口匹配
Point
Line
+display() +fill() +undisplay()
+display() +fill() +undisplay()
Square
+display() +fill() +undisplay()
Circle
+display() +fill() +undisplay()
XXCircle
Adaptee +specificRequest()
Adapter +request()
练习பைடு நூலகம்
• 试着将Shape类,Circle类, XXCircle类 对应到对象适配器/类适配器模式的定义中
真实世界中的适配器
• 想一想Java语言中不同版本中有没有需要 进行适配的
真实世界中的适配器
• 早期java版本中集合(Collection)类型 (例如:Vector,Stack,Hashtable)都实现 了一个elements()方法。该方法返回一个 Enumeration(枚举)
• 新版本中开始使用Iterator(迭代器)接口, 这个接口和枚举接口很像,但不同的是, 迭代器还提供了删除元素的能力。
问题
• 面对遗留代码,这些代码会暴露出枚举器 接口,但我们又希望在新的代码中只使用 迭代器。
• 解决办法
– 构造一个适配器 – 将枚举适配到迭代器
<<interface>>
目标接口
Square
+display() +display()
+fill()
+fill()
+undisplay() +undisplay()
+display() +fill() +undisplay()
• 优秀的编程人员首先会四处寻找替代方案 • 发现有人已经编写好了一个处理圆形的类,
名叫XXCircle • 它并不知道我们的命名规则,而是
在架构层次上的应用
• JDBC驱动软件与适配器模式 • JDBC给出一个客户端通用的界面。每个数据库引擎的JDBC驱动软件
都是一个介于JDBC接口和数据库引擎接口之间的适配器软件 • 抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软
件,即为各个数据库引擎准备的驱动软件。
• JDBC/ODBC桥梁
Adapter模式定义
• 效果:Adapter模式使原有对象能够适应新的类 结构,不受其接口的限制。
• 实现:将原有类包含在另一个类之中。让包含类 与需要的接口匹配,调用被包含类的方法
类的适配器
• 类适配器不是使用组合来适配被适配者,而是继承被适 配者和目标类
Client
Target +request()
– 如果没有合适的JDBC驱动软件,用户也可以通过 ODBC驱动软件把JDBC通过一个JDBC/ODBC桥梁软 件与ODBC驱动软件连接起来,从而达到连接数据库的 目的。
适配器模式
• 适配器现实中到处都是
– 如:中国制造的笔记本电脑带到欧洲使 用,需要一个交流电的适配器
• 面向对象适配器
– 假设有一个软件系统,你希望它能和一 个新的厂商类库搭配使用,但是这个新 厂商所设计出来的接口,不同于旧厂商 的接口
现有系统
厂商类
• 不想改变现有代码 • 也不能改变厂商的代码 • 怎么办?
+displayIt() +fillIt() +undisplayIt()
• 实现Adapter模式
Class Circle extends Shape { private XXCircle myXXCircle; public Circle ( ) { myXXCircle= new XXCircle ( ); } void public display ( ) { myXXCircle.displayIt (); } …