已有的类与新的接口之间不兼容的问题相当普遍,人们已为它找到了一个解决方案。这个解决方案就是适配器。

1 何为适配器 what

适配器的主要作用是把被适配者的行为传递给管道另一端的客户端。

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类一起工作。

实现适配器有两种方式:

1)类适配器:通过继承来适配两个接口。继承Adaptee,遵从<Target>协议。

2)对象适配器:通过组合来适配。遵从<Target>协议,组合了一个队Adaptee的引用。

区别:

类适配器  
只针对单一的具体Adaptee类,把Adaptee适配到Target;

易于重载Adaptee的行为,因为是通过直接的子类化进行的适配;

只有一个Adapter对象,无需额外的指针间接访问Adaptee。

对象适配器

可以适配多个Adaptee及子类;

难以重载Adaptee的行为,需要借助于子类的对象而不是Adaptee本身;

需要额外的指针以间接访问Adaptee并适配器行为。

适配器模式中的角色

1)  目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,额可以是接口。

2)需要适配的类(Adaptee):需要适配的类或是陪着类。

3)适配器(Adaper):通过包装一个需要适配的对象,把原接口转换成目标接口。

2 何时使用适配器模式

1) 系统需要使用现有的类,而这些类的接口不符合系统的接口。

2) 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

3) 两个类所做的事情相同或相似,但是具有不同接口的时候。

4) 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。

5)   使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

3 委托模式主要是适配器模式,也可以实现某些其他设计模式的意图,比如装饰模式。

4 objective-c 协议实现适配器模式

如果要复用某个东西,从面向对象编程的角度来说,就要把那个东西放到对象中。(命令对象NSInvocation,可被放入队列并复用,可以对封装的操作进行撤销和恢复)

线色变更机制的设计与实现:

SetStrokeColorCommand是客户端是Command的子类

Command:NSObject

方法:- (void) execute;

1)<SetStrokeColorCommandDelegate>

- (void) command:(SetStrokeColorCommand *)command didRequestColorComponentsForRed:(CGFloat *)red green:(CGFloat *) blue:(CGFloat *)blue;

//通过传递红绿蓝引用参数返回队里的RGB值

- (void) command:(SetStrokeColorCommand *)command didFinishColorUpdateWithColor:(UIColor *)color;

//当颜色更新过程结束时,此方法将会被调用。命令对象会把自己和更新后的颜色对象传给适配器。

2)实现客户端 SetStrokeColorCommand

SetStrokeColorCommand:Command

实例:id <SetStrokeColorCommandDelegate> delegate

方法:重写 - (void)execute;

- (void)execute

{
  CGFloat redValue = 0.0f;

  CGFloat greenValue = 0.0f;

  CGFloat blueValue = 0.0f;

  [delegate command:self didRequestColorComponetsForRed:&redValue green:&greenValue blue:&blueValue];

  UIColor *color = [UIColor colorWithRed:redValue green:greenValue blue:blueValue alpha:1.0];

    //把它复制给当前CanvasViewController

  CoordinatingController *coordinator = [CoordinatingController sharedInstance];

  CanvasViewController *controller = [coordinator canvasViewController];

  [controller setStrokeColor:color];

  //转发更新成功消息

  [delegate command:self didFinishColorUpdateWithColor:color];

}

3) 创建被适配者

PaletteViewController

#pragma mark SetStrokeColorCommandDelgete methods

- (void) command:(SetStrokeColorCommand *)command didRequestColorComponentsForRed:(CGFloat *)red green:(CGFloat *) blue:(CGFloat *)blue

{

  *red = [redSlider value];

  *green = [greenSlider value];

  *blue = [blueSlider value];

}

- (void) command:(SetStrokeColorCommand *)command didFinishColorUpdateWithColor:(UIColor *)color

{
  [paletteView setBackgroundColor:color];

}

#pragma mark Slider event handler

- (IBAction)onCommandSliderValueChanged:(CommandSlider *)slider

{

  [[slider command] excute];

}

//定义客户端期待的接口

Target

方法:Request NSLog(@"this is a common request");

//定义需要适配的类

Adaptee

方法:SepecificRequst NSLog(@"This is a special request");

//定义适配器

Adapter:Target

方法:重写Request 实际调用SepecificRequst

//客户端代码,对于客户端来说,调用的就是Target的Request

Target target = new Adapter();

[target Request];

5 使用块实现适配器模式

关于块:块实际上是OC对象。块被看做栈中的匿名对象,离开了作用域就会被销毁。块对retain没有实际作用。要想retain块,需要把它移动到堆中。块字面量可以与消息调用定义在一起,但是C函数指针缺无法做到这一点。

跟涉及更为正式的协议与类相比,这种方式使得代码和结构更加简洁,适配器更加直接而随意,却又保持了适配器模式的原汁原味。

OC编程之道-接口适配之适配器的更多相关文章

  1. OC编程之道-创建对象之抽象工厂方法

    定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类.       <AbstractProductA> <AbstractProductB> <Ab ...

  2. OC编程之道-创建对象之工厂方法

    一 何为工厂方法模式?(what) 定义创建对象的接口,让子类决定实例化哪一个类,工厂方法是的一个类的实例化延迟到其子类. 工厂方法创建的对象拥有一组共同的行为,所以往类层次结构中引入新的具体产品并不 ...

  3. OC编程之道-创建对象之单例模式

    一 何为单例singleton模式?(what) 保证一个类只有一个实例,并提供一个访问它的全局访问点. 二 何时使用单例模式?(where) 1类只能有一个实例,而且必须从一个为人熟知的访问点对其访 ...

  4. OC编程之道-创建对象之原型模式

    一 什么是原型模式?(what) 有些对象的创建代价过大或过于复杂,要是可以重建相同的对象并作轻微的改动,事情会容易的多(效率变高).典型的例子是复制组合结构(eg树形结构),从零开始构建一个树型组合 ...

  5. OC编程之道-创建对象之生成器模式

    生成器模式也叫建造者模式,一般是用来构造复杂对象的一种模式.client(客户)-director(指导者)-builder(构造者)-product(产品). 生成器模式能帮助构建设计部件与表现的各 ...

  6. Java并发编程75道面试题及答案

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  7. Objective-C设计模式——外观Faced(接口适配)

    外观模式 外观设计模式和适配器差不多,不过它门对对象控制的粒度不同,适配器一般只是控制一个系统和客户端的对接.外观则是用来抽象多个系统一起工作. 外观一般具有多个子系统,所以外观应持有多个子系统的引用 ...

  8. [.net 面向对象编程基础] (16) 接口

    [.net 面向对象编程基础] (16) 接口 关于“接口”一词,跟我们平常看到的电脑的硬件“接口”意义上是差不多的.拿一台电脑来说,我们从外面,可以看到他的USB接口,COM接口等,那么这些接口的目 ...

  9. C#编程利器之三:接口(Interface)【转】

    C#编程利器之三:接口(Interface) C#接口是一个让很多初学者容易迷糊的东西,用起来好象很简单,定义接口,然后在里面定义方法,通过继承与他的子类来完成具体的实现.但没有真正认识接口的作用的时 ...

随机推荐

  1. 分享一些自己的学习过程和学习方法(来自daimajia)

    每天,都会有人在微博上私信我,问我关于学习和成长的问题.这种问题我一般都不会回复某个j,毕竟每个人的情况不一样,每个人对待事物的性格也不一样,我不能夸下海口的说,你看某本书几个月就能如何如何,我能做的 ...

  2. java的字符串截取

    import java.util.Date; import java.text.SimpleDateFormat; Date now = new Date(); def portcodes = new ...

  3. Java开发环境搭建——Tomcat配置

    指定tomcat的JDK版本可能由于种种原因,系统的JAVA_HOME配置的JDK版本并不是当前需要的版本,而tomcat默认使用的是JAVA_HOME的JDK.可以通过修改tomcat/bin/ca ...

  4. css随笔1

    1.简单清除浏览器样式 *{        padding: 0px;        margin: 0px;    } 2.得到屏幕范围的div html,body{        width: 1 ...

  5. Spring(Model)

    一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架 分层架构,一站式(full-stack),高内聚低耦合,允许客户端JavaScript远程调用服务端JAVA类方法 应用中的对象不依赖于S ...

  6. PHP中explode和implode的区别

    字符串的连接与分割是非常重要的两个内容,通过其可以将数组按照指定的规则转换成字符串,也可以将字符串按照指定的规则进行分割,返回一个数组.其应用范围很广,如在购物网站的购物车,在线投票系统等.这两项技术 ...

  7. CentOS 7.0安装配置Vsftp服务器

    一.配置防火墙,开启FTP服务器需要的端口 CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop fi ...

  8. iOS多线程-RunLoop简介

    什么是RunLoop? 从字面上来看是运行循环的意思. 内部就是一个do{}while循环,在这个循环里内部不断的处理各种任务(比如:source/timer/Observer) RunLoop的存在 ...

  9. Chrome Error Code:ERR_UNSAFE_PORT

    最近在IIS上部署一些测试站点,发现87端口在使用Chrome浏览的时候打不开,但是使用IE却OK~ 点击更多信息,提示错误代码:ERR_UNSAFE_PORT 不安全的端口?这是什么情况? 度娘发现 ...

  10. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...