swift 之设计模式 适配器
大学的时候,有一个《近世代数》的教授,他上课从来不看课本,并且也不按课本来讲解课程,但是他讲的东西比书本深刻形象(幽默,口才杠杠的),有层次感,除了授业,他还经常给我讲一些为人处世,做学问的方法【他是我尊敬的老师之一】。 学过这门课的人都知道这门课全是理论,群论,环,域等,各种理论证明,各种装逼各种飞。 现在课本上的还回去的基本上还回去了,留下更多的就是他给我讲的一些方法,在这里引入一下:
掌握一个新概念:
1. 背景引入,为什么会有这个概念产生
2. 是什么?拆分概念的各种条件,名词,结论
3. 熟悉相关例子
4. 做题
5. 笔记总结,下次上课不看书,用自己的语言表述这个概念,举个例子【记忆中,每次讲完一张,他就要求我们做读书笔记,画知识图】
今天为什么会谈及上面这些,我觉得像我们做程序员的,学习是必须的,高效的学习东西也是必须的,把东西学到脑子里运用到项目中那也是理所当然的。对于一个新的东西,我们也可以效仿这位老师的一些方法。
我个人比较推崇: from(背景/problem) -- what --- where/when(产生的时机/examples) ---- how(思路) ---- do(上代码) -- summary(总结)
废话不多说,上菜:
适配器:
from:
生活:对于这个概念,我头一想到的就是充电器,我们都知道我们国家的是220v的标准电压,日本的100v, 美国的又是不一样,那么我们有一个手机,如果要到这三个地方旅游,那么我带一个充电器是不是在其他国家就用不了。没到不同的国家我们的充电器就要换个。当然你说苹果的就不用,它的是万能充电器,全球都适用。
项目: 在项目中,我们也会有这种问题,比如你有个自定义view,然后你在controller要给这个view传递数据给他,我们经常会这样做:
1. 直接给view上的控件赋值
2. 把view需要的数据抽象成一个对象,然后传这个对象给view。
这两种方法都可行,but,都存在一些问题:
对于1,直接赋值,如果view复杂起来是不是都要写很多这样的代码,如果某一天换了个字段,是不是每个地方都要进行改动,这种的代码耦合度太高,不可取。
对于2,这种方法我现在都还在使用,之前我也不知道这种方法到底有什么缺点,但是当有一天我碰到有两个数据模型都可以给view进行赋值,但是我在view上只进行了对其中一个模型的绑定,这个时候我是不是要在view上再添加一个另一个模型的绑定方法,对于这种写法,我个人感觉很别扭,所以就有代码灵活性的问题。
what:
那什么是适配器呢?
适配器设计模式是一种结构型设计模式, 它的作用是把一个类的接口转换成客户希望的另外一个接口,从而使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
结构型设计模式:
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易体现出设计人员水平的高低,这里有7个具体的结构型模式可供研究,它们分别是:
外观模式(Facade)
适配器模式(Adapter)
代理模式(Proxy)
装饰模式(Decorator)
桥模式(Bridge)
组合模式(Composite)
享元模式(Flyweight)
我们现在所说的设计模式是 Gof 下的 Behavioral | Creational | Structural 的Structural
In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.
Source: wikipedia.org
适配器有两种实现方式:
1. 类适配器
Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口
2. 对象适配器
另外一种适配器模式是对象适配器,它不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式
where/when:
希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,就拿我上面的问题 ,或者在 遗留代码复用、类库迁移 等方面。
适用场景:
1、已经存在的类的接口不符合我们的需求;
2、创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;
3、在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。
how:
思路其实就如2上的两张UML,这里不做简述了
do:
import UIKit protocol AnimingProtocol {
var angleV: NSNumber { get }
var angleH: NSNumber { get }
} // Adaptee
struct AdapteeTarget {
let angleHorizontal: Double
let angleVertical: Double
init(angleHorizontal: Double, angleVertical: Double) {
self.angleHorizontal = angleHorizontal
self.angleVertical = angleVertical
}
} // Adapter
struct AdapterTarget: AnimingProtocol {
private let target: AdapteeTarget
var angleV: NSNumber {
return NSNumber(double: target.angleVertical)
}
var angleH: NSNumber {
return NSNumber(double: target.angleHorizontal)
}
init(target: AdapteeTarget) {
self.target = target
}
}
summary:
适配器模式有点如上,其缺点也存在,很多东西本来可以直接了当,用了适配器后就多了一大坨代码。当然如果把上面的实现在拆分下文件,那么显然如果不知道适配器原理的人 就很难理解代码why了。但是对于项目的长远来看,如果可以写出可变性好的代码,偶尔降低代码的可读性 也是可以接受的,毕竟这些模式都很金典,看不懂只能说明学得还不够多。
对于do上代码你认为他是类适配器还是对象适配器?
swift 之设计模式 适配器的更多相关文章
- iOS设计模式 - 适配器
iOS设计模式 - 适配器 效果 说明 1. 为了让客户端尽可能的通用,我们使用适配器模式来隔离客户端与外部参数的联系,只让客户端与适配器通信. 2. 本教程实现了适配器模式的类适配器与对象适配器两种 ...
- 设计模式--适配器(Adapter)模式
今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...
- ABAP设计模式——适配器
计算机科学中的大多数问题都可以通过增加一层间接性来解决. ——David Wheeler 适配器模式(Adapter Design Pattern),是一个广泛应用于真实世界和面向对象编程语言的设计 ...
- 设计模式——适配器(Adapter)模式
概述 什么是适配器?在我们生活中的适配器比如插头转换器(中标转美标).USB接口转换器(type-c转苹果),电脑电源适配器(交流电转低电压直流)等.像这种将两者有差异的东西通过适配器使他们成为相互适 ...
- Objective-C设计模式——适配器Adapter(接口适配)
适配器模式 适配器模式通俗来讲,其实就是对客户端添加新的类但却不修改客户端和新的类的接口.此时我们需要自己来实现适配,在适配器模式中有Target对象,即客户端所需要的接口对象,Adaptee对象,即 ...
- Head First设计模式——适配器和外观模式
前言:为什么要一次讲解这两个模式,说点骚话:因为比较简单(*^_^*),其实是他们两个有相似和有时候我们容易搞混概念. 讲到这两个设计模式与另外一个“装饰者模式”也有相似,他们三个按照结构模式分类都属 ...
- 设计模式 适配器-Adapter
适配器模式:将一个类的接口,转换成客户期望的另一个接口.适配器让原本接口不兼容的类可以合作无间. 直接上图.下面是对象适配器的类图.由于Java不支持多继承.所以这是Java的适配器实现方式. 结合H ...
- Swift辛格尔顿设计模式(SINGLETON)
本文已更新为2.0语法,具体查看:一叶单例模式 一.意图 保证一个类公有一个实例.并提供一个訪问它的全局訪问点. 二.使用场景 1.使用场景 当类仅仅能有一个实例并且客户能够从一个众所周知的訪问点訪问 ...
- 系统架构-设计模式(适配器、观察者、代理、抽象工厂等)及架构模式(C/S、B/S、分布式、SOA、SaaS)(干货)
博客园首页是需要分享干货的地方,今天早上写的<HRMS(人力资源管理系统)-从单机应用到SaaS应用-系统介绍>内容下架了,所以我就按照相关规定,只分享干货,我把之前写完的内容整理发布上来 ...
随机推荐
- Linux下服务器重启
Linux关闭和重启系统一般使用相同的命令可以实现. 在Linux系统下常用在关机/重启命令有shutdown.halt.reboot和init,但每个命令的内部工作过程是不同的. 1.shutdow ...
- 如何使用Flexbox和CSS Grid,实现高效布局
CSS 浮动属性一直是网站上排列元素的主要方法之一,但是当实现复杂布局时,这种方法不总是那么理想.幸运的是,在现代网页设计时代,使用 Flexbox 和 CSS Grid 来对齐元素,变得相对容易起来 ...
- Linux下识别分区文件系统类型
Linux下挂载文件系统有时候需要填写文件系统.但有的设备拿到手还不知道文件系统,这种情况,可以用 parted命令 # parted /dev/vda GNU Parted 3.2 Using /d ...
- jdk版本切换
安装1.6/1.7/1.8版本的jdk 保存jdk的安装目录下的文件 卸载所有jdk 将jdk各个版本拷贝到一个文件夹下 配置环境变量 因为安装之后系统会有注册表之类的文件,单纯的修改环境是不会修改成 ...
- 网站如何集成百度UEditor编辑器
在平时的网站维护使用过程中,富文本编辑器是网站必不可少的元素之一.现在市面上各种编辑器功能设计参差不齐,自己做了几个网站都是用蝉知建站系统做的,而蝉知默认内置的编辑器是KindEditor,功能简单, ...
- 简单Elixir游戏服设计- 游戏玩法介绍
抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...
- .net通用防SQL注入漏洞程序(Global.asax方式)
原理很简单:使用Global.asax中的Application_BeginRequest(object sender, EventArgs e)事件,实现表单或URL提交数据的获取,然后通过SQLI ...
- HDU2066 一个人的旅行 最短路基础
新手熟悉一下迪杰斯特拉... 一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- C#微信公众号/订阅号开发 接口源码
using System; using System.Web; using System.IO; using System.Text; using System.Web.Security; using ...
- cocos2dx - 伤害实现
接上一节内容:cocos2dx - 生成怪物及AI 本节主要讲如何通过创建简单的矩形区域来造成伤害 在小游戏中简单的碰撞需求应用box2d等引擎会显得过于臃肿复杂,且功能不是根据需求定制,还要封装,为 ...