设计模式-适配器模式(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描写叙述符,那么该函数必须重载其基类中的同名函数,否则代码将无法 ...
随机推荐
- 1.24 Python知识进阶 - 类与对象
类 语法格式: class Dog(object): print("the dog is barking ...") Dog为类名,object为要继承的基类,Dog类会从基类ob ...
- 轻松学习Linux之用户账户管理及实例
Linux用户管理基础 (下载清晰视频:http://down.51cto.com/data/158699) 轻松学习Linux之用户账户管理的实例-跨硬盘移动数据 (此处视频不清楚下按下面地址下载清 ...
- Android 用Socket实现PC和手机的文件传输
PC服务器端代码: /* * PC与<a href="http://lib.csdn.net/base/android" class='replace_word' title ...
- 字符设备驱动-----Linux中断处理体系结构
一.中断处理体系结构的初始化 Linux内核将所有的中断统一编号,使用一个irq_desc结构数组来描述这些中断;每个数组项对应一个中断,也可能是一组中断,它们共用相同的中断号,里面记录了中断的名称. ...
- jmeter实现分布式压测步骤
环境说明:安装与控制机相同版本的jdk与jmeter 1.修改控制机中的jmeter.properties文件 将<remote_hosts=127.0.0.1>改为<remote_ ...
- mysql-5.7.19-winx64服务无法启动解决方案
解压mysql压缩包时没有data文件夹,不要手动创建,在cmd下直接运行命令: mysqld –initialize-insecure,data文件夹会自动生成,注意单词千万不要拼错,不要写成–in ...
- elasticsearch选举master
数据节点确定了master以后.会开启MasterPinger线程来与其保持心跳通信的逻辑假设通信过程中链接断开,会通过MasterNodeFailureListener监听器进行回调处理处理过程中会 ...
- Netty推荐addListener回调异步执行
说明 Netty推荐使用addListener的方式来回调异步执行的结果,这种方式优于Future.get,能够更精确地把握异步执行结束的时间. 错误理解使用addListener的方式 代码如下: ...
- 3. ZAB与Paxos算法的联系与区别。
转自:https://blog.csdn.net/en_joker/article/details/78665809 ZAB协议并不是Paxos算法的一个典型实现,在讲解ZAB和Paxos之间的区别之 ...
- JS实现联想自动补齐功能
<!DOCTYPE HTML> <html> <head> <meta charset = "utf-8"> <title&g ...