用来解决接口适配问题的三种模式:适配器模式,桥接模式,外观模式。

一,概念

  适配器模式,将一个类的结构转换成用户希望的另一个接口,使得原本接口不兼容的类能在一起工作。换句话说,适配器模式就是链接两种不同种类的对象,使其很好的协同工作。(说的很美吧,我抄的,百度里每个帖子都会这样说。简单说就是你笔记本是19v供电,但是家里面电压是220v,这时候想要充电,就需要一个笔记本的220v转19v电源适配器)。

  有两种实现结构(类的适配器,对象的适配器),还有说三种(接口的适配器方式),额。

二,模式结构图

  了解三个角色,结合结构图理解:

    Target:目标角色定义客户端具体使用的接口,也就是我们的期望接口,简单一点就是协议,协议定义我们需要的接口

    Adaptee:源角色,你想把“谁”转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。

    Adapter:适配器角色,适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,他的职责非常简单:把源角色转换为目标角色。

  类的适配器模式:

  

  Adapter是一个Target(目标接口)类型,同时也是一个Adaptee(被适配的类)类型。Adapter重载Target的request方法,但没有重载Adaptee的specificRequest方法,而是在其request方法中调用父类的specificRequest方法(即:[super specificRequest])。当request方法在运行时,向Adaptee发送super消息时,Adaptee按自己的方式执行specificRequest方法。注意:只有当Target是协议而不是类时,类适配器才能用Objective-C实现。

  对象的适配器模式:

  

  Target和Adapter之间的关系与类适配器相同,而Adapter和Adaptee之间的关系从“属于(继承)”变成了“包含(组合引用)”。这种情况下Adapter持有一个对Adaptee的引用,在request方法中,Adapter发送[adaptee specificRequest]消息,以间接方法Adaptee的specificRequest方法,然后实现客户端请求的其他部分。

三,使用场景:(也是copy的,多读读回忆下项目代码就能理解了)

  1:你想使用一个已经存在的类,而它的接口不符合你的需求,即已有类的接口与需求不匹配
  2:你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作
  3:(仅适用于对象Adapter)你想使用一些已存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口,对象适配器可以适配它的父类接口

四,Demo演示:
  下面有个场景,已经存在一个UniversulAudioPlayer类,可以进行音频的播放。但是ViewController端需要的是一个遵守了AudioPlayerProtocol协议接口的类对象 AudioPlayerProtocol协议规范了ViewController调用接口,她和UniversulAudioPlayer已经实现的接口并不匹配。代码如下:

Target

  1. protocol AudioPlayerProtocol {
  2.  
  3. /// setting media source
  4. ///
  5. /// - Parameter url: source url
  6. /// - Returns: whether success
  7. func prepareWithUrl(url: URL) -> Bool
  8.  
  9. /// jump to playing time point
  10. ///
  11. /// - Parameter time: the time point 0 - media.duration
  12. /// - Returns: whether success
  13. func jumpTo(time: TimeInterval) -> Bool
  14.  
  15. /// increase valume,add 0.1 once, value0 - 1
  16. ///
  17. /// - Returns: Voide
  18. func increaseVolume() -> Void
  19.  
  20. /// reduce Volume
  21. ///
  22. /// - Returns: Void
  23. func reduceVolume() -> Void
  24.  
  25. /// start to play the audio
  26. ///
  27. /// - Returns:
  28. func play() -> Void
  29.  
  30. /// pause the audio
  31. ///
  32. /// - Returns:
  33. func pause() -> Void
  34.  
  35. /// resume to play
  36. ///
  37. /// - Returns:
  38. func resume() -> Void
  39. }

Adapee

  1. class UniversulAudioPlayer: NSObject {
  2.  
  3. private var url: URL?
  4. private var duration: TimeInterval = 0
  5. private var volumeValue: Float = 0
  6. private var timeValue: TimeInterval = 0
  7.  
  8. var volume: Float{
  9. set{
  10. if newValue <= 0 {
  11. self.volumeValue = 0
  12. }else if newValue >= 1{
  13. self.volumeValue = 1.0
  14. }else{
  15. self.volumeValue = newValue
  16. }
  17. print("new volume: \(self.volumeValue)")
  18. }
  19. get{
  20. return self.volumeValue
  21. }
  22. }
  23.  
  24. var time: TimeInterval{
  25. set{
  26. if newValue >= 0.0 && newValue <= duration {
  27. self.timeValue = newValue
  28. print("new time: \(newValue)")
  29. }
  30. }
  31. get{
  32. return self.timeValue
  33. }
  34. }
  35.  
  36. func audioWithUrl(url: URL) -> Bool {
  37. print("setting url: \(url)")
  38. self.duration = 300;
  39. self.url = url;
  40. return true
  41. }
  42.  
  43. func playAudio() {
  44. if url != nil {
  45. print("start\resume to play audio \(url!)")
  46. }else{
  47. print("play fail")
  48. }
  49. }
  50.  
  51. func pauseAudio() {
  52. if url != nil {
  53. print("pause audio \(url!)")
  54. }else{
  55. print("play fail")
  56. }
  57. }
  58. }

Client

  1. class ViewController: UIViewController {
  2.  
  3. var player: AudioPlayerProtocol!
  4.  
  5. override func viewDidLoad() {
  6. super.viewDidLoad()
  7. // player = MyUniversulAudioPlayer()
  8. player = TheUniversulAudioPlayer()
  9. player.prepareWithUrl(url: URL(string: "http://www.y.com/music/a.mp3")!)
  10. }
  11.  
  12. //按钮事件
  13.  
  14. @IBAction func playBtnClicked(_ sender: Any) {
  15. player.play()
  16. }
  17.  
  18. @IBAction func pauseBtnClicked(_ sender: Any) {
  19. player.pause()
  20. }
  21.  
  22. @IBAction func resumeBtnClicked(_ sender: Any) {
  23. player.resume()
  24. }
  25.  
  26. @IBAction func increaseVolumeBtnClicked(_ sender: Any) {
  27. player.increaseVolume()
  28. }
  29.  
  30. @IBAction func reduceVolumeBtnClicked(_ sender: Any) {
  31. player.reduceVolume()
  32. }
  33.  
  34. }

所以,就需要我们做一个适配器
1,类的适配器模式:

  1. class MyUniversulAudioPlayer: UniversulAudioPlayer, AudioPlayerProtocol {
  2. func prepareWithUrl(url: URL) -> Bool {
  3. return super.audioWithUrl(url: url)
  4. }
  5.  
  6. func jumpTo(time: TimeInterval) -> Bool {
  7. super.time = time
  8. return true
  9. }
  10.  
  11. func increaseVolume() {
  12. self.volume += 0.1
  13. }
  14.  
  15. func reduceVolume() {
  16. self.volume -= 0.1
  17. }
  18.  
  19. func play() {
  20. self.playAudio()
  21. }
  22.  
  23. func pause() {
  24. self.pauseAudio()
  25. }
  26.  
  27. func resume() {
  28. self.playAudio()
  29. }
  30.  
  31. }

2,对象的适配器模式

  1. class TheUniversulAudioPlayer: AudioPlayerProtocol {
  2.  
  3. private var universulPlayer = UniversulAudioPlayer()
  4.  
  5. func prepareWithUrl(url: URL) -> Bool {
  6. return universulPlayer.audioWithUrl(url: url)
  7. }
  8.  
  9. func jumpTo(time: TimeInterval) -> Bool {
  10. universulPlayer.time = time
  11. return true
  12. }
  13.  
  14. func increaseVolume() {
  15. universulPlayer.volume += 0.1
  16. }
  17.  
  18. func reduceVolume() {
  19. universulPlayer.volume -= 0.1
  20. }
  21.  
  22. func play() {
  23. universulPlayer.playAudio()
  24. }
  25.  
  26. func pause() {
  27. universulPlayer.pauseAudio()
  28. }
  29.  
  30. func resume() {
  31. universulPlayer.playAudio()
  32. }
  33.  
  34. }

  

设计模式-(6)适配器 (swift版)的更多相关文章

  1. iOS可视化动态绘制八种排序过程(Swift版)

    前面几篇博客都是关于排序的,在之前陆陆续续发布的博客中,我们先后介绍了冒泡排序.选择排序.插入排序.希尔排序.堆排序.归并排序以及快速排序.俗话说的好,做事儿要善始善终,本篇博客就算是对之前那几篇博客 ...

  2. Swift版iOS游戏框架Sprite Kit基础教程下册

    Swift版iOS游戏框架Sprite Kit基础教程下册 试读下载地址:http://pan.baidu.com/s/1qWBdV0C 介绍:本教程是国内唯一的Swift版的Spritekit教程. ...

  3. Swift版音乐播放器(简化版),swift音乐播放器

    这几天闲着也是闲着,学习一下Swift的,于是到开源社区Download了个OC版的音乐播放器,练练手,在这里发扬开源精神, 希望对大家有帮助! 这个DEMO里,使用到了 AudioPlayer(对音 ...

  4. 快速排序OC、Swift版源码

    前言: 你要问我学学算法在工作当中有什么用,说实话,当达不到那个地步的时候,可能我们不能直接的感觉到它的用处!你就抱着这样一个心态,当一些APP中涉及到算法的时候我不想给其他人画界面!公司的项目也是暂 ...

  5. swift版的CircleView

    swift版的CircleView 效果图 源码 // // CircleView.swift // CircleView // // Created by YouXianMing on 15/10/ ...

  6. swift版的GCD封装

    swift版的GCD封装 说明 本人针对swift封装了GCD,包括GCDQueue,GCDGroup,GCDTimer以及GCDSemaphore,使用较为便利. 源码 https://github ...

  7. swift版的StringAttribute

    swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...

  8. swift版的元组

    swift版的元组 说明 元组的内容并不多,使用的话跟普通变量类似,以下是测试源码: // // ViewController.swift // Tuples // // Created by You ...

  9. swift版的枚举变量

    swift版的枚举变量 swift的枚举类型跟普通的类是极为类似的,使用的时候,请不要以为他是一个常量,以下是测试用源码 // // ViewController.swift // SwiftEnum ...

  10. 关东升的iOS实战系列图书 《iOS实战:入门与提高卷(Swift版)》已经上市

             承蒙广大读者的厚爱我的 <iOS实战:入门与提高卷(Swift版)>京东上市了,欢迎广大读者提出宝贵意见.http://item.jd.com/11766718.html ...

随机推荐

  1. 【笔记】mysql入门语句8条

    1.连接到数据库服务器 mysql -h host -uroot -pXXXX 2.查看所有库 show databases; 3.选库 use 库名 4.查看库下面的表 show tables; 5 ...

  2. centos7 ftp 500 OOPS: cannot change directory:/var/ftp/xutong/

    在设置多用户登录的时候 该指定的用户xutong对于上级目录/var/ftp 没有访问权限 修改一下上级目录的权限 chmod /var/ftp 对于ftp多用户访问的配置修改也做一个记录 以是设置F ...

  3. 洛谷2016 战略游戏 (0/1状态的普通树形Dp)

    题意: 给出一个树,覆盖树上某一个点的花费为w[i],求树上每一条边至少有一个点覆盖的最小花费. 细节: 1.一条边的两端可以均被覆盖,但是不能存在一条边的两端都不被覆盖. 2.可能存在 分析: 对于 ...

  4. PS日记二(调色:色阶,曲线,色相/饱和度,色彩平衡,蒙板)

    基础知识一:在PS操作中为什么要复制图层(ctrl+J)? 答:复制图层主要是为了 备份原图层,在副本中进行操作 如果说你副本弄坏了,还有原来的PS复制图层一方面是保全原图.二是因为图层是ps操作的基 ...

  5. Sed命令基础操作

    sed用法的小技巧 (1)在查找范围时不需要用到替换,所以不用s; (2)当只需要打印被修改行时,可以使用-n 和 –p 选项,注意二者一定配合使用: 3种方式指定命令行上的多重指令 (1)用逗号分隔 ...

  6. Hadoop JVM调整解决 MapReduce 作业超时问题

    摘要:由于业务需要,在mapreduce汇总时需要关联两个基础表,一个60M左右,不影响mr运行,另一个表,大小约为380M,行数为1700万行左右,在默认配置下,一旦加载这个数据就会在reduce阶 ...

  7. Flex4分模块下样式动态加载步骤及相关问题的解决

    1.  给应用程序编写CSS文件 (1)在项目下创建CSS文件(任意路径,可以多个).本例在src下创建了5个样式文件 (2)Flex支持的CSS文件定义如下: a)  type selector(类 ...

  8. easyui combotree选项重复

    现象 编辑,赋值出现重复选项 原因 值之间有空格,比如我取值是3, 4, 6要改成3,4,6 注意:数值之间的空格去掉了

  9. “约定优于配置”与Magento改造尝试四之block、helper和model载入

    暂定本章为这个系列最后一章,还是继续沿用模块的别名(alias)概念 <modules> <Mage_Wishlist> <version>1.6.0.0</ ...

  10. SDUTOJ 2475 Power Strings

    <pre class="cpp" name="code">#include<iostream> #include<stdio.h& ...