设计模式-适配器模式(Go语言描写叙述)
在上一篇博客设计模式-策略模式(Go语言描写叙述)中我们用最简单的代码用go语言描写叙述了设计模式中的策略模式,用最简单的实例来描写叙述相信能够让刚開始学习的人能够非常轻松的掌握各种设计模式。继上篇博客,我们接着用相同简单的代码来了解一下适配器模式。
适配器模式介绍
说起适配器模式,相信非常多做android的同学第一印象就是AdapterView的Adapter,那它是干嘛用的呢?为什么要叫adapter呢?要了解这个问题。我们首先来看看适配器模式的定义:
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类能够一起工作。——Gang of Four
恩,看起来好像有点迷糊,举个样例吧:
我电脑的电源是三个插头(也就是有地线)的那种,不知道为啥学校的插座都是两个插孔的,哎呀,这可咋办啊!同学建议我们买个转换器,这种转换器有三个插孔,我的电源能够插进去,同一时候它还有两个插头,能够插进学校的插座里,嘿嘿,同学真聪明,这么easy的就攻克了我的问题。
在上面的样例里,那个转换器也能够叫做适配器,我们如今要说的适配器模式灵感就是来自上述所述的实际生活中遇到的问题。那在我们程序设计中会遇到什么样的问题呢? 再来看个样例:
应老师的要求,我们如今须要做一个音乐播放器,如今我算是知道一点面向对象的原则了,所以我首先设计了一个接口。这个接口有一个playMusic的方法,接着我非常轻松的利用这个接口设计出了一个音乐播放器,音乐控制器通过调用playMusic能够完美的播放不论什么音乐。啧啧啧,高兴中…老师对我的音乐播放器也非常惬意。只是他又提出了新的需求,让我的音乐播放器也能够播放游戏的声音。并给了我一个播放游戏声音的类。这个类也非常easy。仅仅有一个playSound方法,尽管非常easy,可是如今我困惑了,由于我设计的音乐控制器仅仅认识playMusic而不认识playSound,难道我要又一次设计我的音乐控制器吗?正当我苦恼的时候,同学出如今了我身后,轻声的告诉我:“适配器模式能够完美的解决你的问题,你仅仅须要写一个Adapter实现你的音乐播放接口,在这个Adapter的playMusic中去调用游戏声音播放器的playSound方法就能够了。
”听了同学的话。我突然恍然大悟。原来这就是适配器模式!
好了。通过上面的三个小段子,相信大家对适配器模式应该了有了大概的认识,以下还是用一张结构图来清晰的描写叙述一下什么是适配器模式吧。
通过上面的图我们也能够看出来,适配器要做的事情就是让我们写的野实现适配到系统须要的标准实现上。以下我们迅速进去代码模式,让代码告诉我们适配器模式张啥样!
代码实现
代码实现环节,我们还是用上面那个音乐播放器的样例,首先设计一个音乐播放的接口:
package player
type Player interface {
PlayMusic()
}
这个接口仅仅有一个方法PlayMusic
,系统通过调用PlayMusic
这种方法达到播放音乐的目的。
在来看看我们播放音乐的实现。
package player
import "fmt"
type MusicPlayer struct {
Src string
}
func (p MusicPlayer) PlayMusic() {
fmt.Println("play music: " + p.Src)
}
MusicPlayer
有一个方法是PlayMusic()
,所以它实现了Player
接口。来让我们的音乐播放器播放器来吧,
package main
import . "./player"
func main() {
var player Player = MusicPlayer {Src:"music.mp3"}
play(player)
}
func play(player Player) {
player.PlayMusic()
}
代码也超级简单,一个play
方法去调用了Player
的实现的PlayMusic
方法。
来看看结果,
如今我们的音乐播放器能够播放歌曲了。仅仅须要给出一个歌曲的路径就ok,只是如今我们还须要播放游戏声音。而且给了我们一个这种实现。
package player
import "fmt"
type GameSoundPlayer struct {
Src string
}
func (p GameSoundPlayer) PlaySound() {
fmt.Println("play sound: " + p.Src)
}
GameSoundPlayer
也是有一个Src
属性,也有一个方法,只是这种方法叫PlaySound
。并非我们须要的PlayMusic
,那可咋办呢?别忘了咱们的play
方法
须要的是一个Player
的实现,并自己主动调用了PlayMusic
方法,以下本节的主角-GameSoundAdapter
出场。
package player
type GameSoundAdapter struct {
SoundPlayer GameSoundPlayer
}
func (p GameSoundAdapter) PlayMusic() {
p.SoundPlayer.PlaySound()
}
GameSoundAdapter
有一个GameSoundPlayer
类型的属性。它就是我们上面的那个游戏声音播放器。GameSoundPlayer
另一个方法名字叫PlayMusic
。所以GameSoundPlayer
实现了Player
接口,我们能够把它用于player
方法中,在PlayMusic
中我们是调用的GameSoundPlayer
的PlaySound
来播放声音的。
来看看我们这个适配器适配的咋样,
package main
import . "./player"
func main() {
gameSound := GameSoundPlayer {Src:"game.mid"}
gameAdapter := GameSoundAdapter {SoundPlayer:gameSound}
play(gameAdapter)
}
func play(player Player) {
player.PlayMusic()
}
看main函数中,首先我们还是有一个GameSoundPlayer
类型的变量,然后将它赋值给了GameSoundAdapter
的SoundPlayer
属性。以下调用GameSoundAdapter
的PlayMusic
方法,就能够间接的调用GameSoundPlayer
的PlaySound
方法了,这样我们就轻松的将GameSoundPlayer
适配到了Player
。
来看看结果:
总体来看我们的代码还是非常easy,只是简单的代码已经将适配器模式解说的非常清晰了,那最后我们来思考一个问题,适配器模式体现了哪些面向对象的设计原则呢?针对接口编程有木有? 开闭原则有木有?
好了。适配器模式我们就讲到这里,最后是文章的实例代码下载:http://download.csdn.net/detail/qibin0506/9420484
设计模式-适配器模式(Go语言描写叙述)的更多相关文章
- 数据结构—单链表(类C语言描写叙述)
单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...
- 数据结构-二叉树的遍历(类C语言描写叙述)
遍历概念 所谓遍历(Traversal)是指沿着某条搜索路线.依次对树中每一个结点均做一次且仅做一次訪问.訪问结点所做的操作依赖于详细的应用问题. 遍历是二叉树上最重要的运算之中的一个,是二叉 ...
- 设计模式-策略模式(Go语言描写叙述)
好久没有更新博客了.近期也是在忙着充电,今天这篇博客開始,我们来了解一下设计模式. 设计模式 那什么是设计模式呢?首先来看看我从百科上copy下来的概念吧. 设计模式/软件设计模式(Design pa ...
- 【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)
插入排序基本思想 每次将一个待排序的记录按其keyword大小插入到前面已经拍好序的子文件的适当位置,直到全部记录插入完毕为止. 直接插入排序 基本思想 直接插入排序的基本操作是将一个记录插入到已排好 ...
- 【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)
选择排序的基本思想 每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,知道所有记录排序完毕.主要有两种选择排序方法:直接选择排序(或称简单选择排序)和堆排序. 直接选择排序 ...
- Python描写叙述符(descriptor)解密
Python中包括了很多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...
- 20. 星际争霸之php设计模式--适配器模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Java设计模式——适配器模式
JAVA 设计模式 适配器模式 用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器 ...
- 【c++】虚函数描写叙述符override
在C++11中为了帮助程序猿写继承结构复杂的类型,引入了虚函数描写叙述符override,假设派生类在虚函数声明时使用了override描写叙述符,那么该函数必须重载其基类中的同名函数,否则代码将无法 ...
随机推荐
- webservie授权调用
Dim usercode As String = System.Configuration.ConfigurationSettings.AppSettings("SAPWebServiceU ...
- 1.17 Python基础知识 - 迭代器和生成器初识
可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象. 列表解析表达式:可以简单高效处理一个可迭代对象,并生成结果列表 示例代码: [ i ** 2 for i in range(10) ] ...
- [Javascript] Iterate Over Items with JavaScript's for-of Loop
In this lesson we will understand the For Of loop in Javascript which was introduced in ES6. The for ...
- 几个经常使用的cmd命令
compmgmt.msc 计算机管理 devmgmt.msc 设备管理器 diskmgmt.msc 磁盘管理工具 dfrg.msc 磁盘碎片整理 eventvwr.msc 事件查看器 fsm ...
- WebForm使用JQuery实现DropDownList无刷新联动
目录(?)[-] 1 JS代码 2 页面相关控件用的是平台封装的控件普通DropDownList也可以 3 后台C代码 注意事项 原来用的微软封装的Ajax控件UpdatePannel和Scri ...
- PHP服务器环境打开配置文件
MAC 1. cd /usr/local/etc/nginx/servers vim www.xxx.com 2. 在/usr/local/etc/nginx/servers目录下,不同的 .con ...
- 【Codeforces Round #446 (Div. 2) C】Pride
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 想一下,感觉最后的结果肯定是从某一段开始,这一段的gcd为1,然后向左和向右扩散的. 则枚举那一段在哪个地方. 我们设这一段中所有的 ...
- MySQL主从复制之Mycat简单配置和高可用
什么是Mycat 1.Mycat就是MySQL Server,而Mycat后面连接的MySQL Server,就好象是MySQL的存储引擎,如InnoDB,MyISAM等.因此,Mycat本身并不存储 ...
- J实现时间格式的转换(附加对象的转换)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 再记AE与AO的区别与联系
原文地址:转:ArcObjects与ArcEngine作者:梦游 ArcObjects(简称AO),一般都是指ArcGIS Desktop版本的组件开发集,即需要安装ArcGIS桌面版软件后才能安 ...