美文网首页
设计模式的学习笔记

设计模式的学习笔记

作者: 乡村武装青年 | 来源:发表于2016-03-19 02:03 被阅读138次

    起因是这样的,还记得夏天的时候.再一次上班的路上,和前公司前端大牛闲聊说道Facebook开源的一个库,里面都是用url作为驱动,进行VC之间的跳转.当时一知半解,就觉得这样设计所有的页面或者view更像一个组件,可以通过url被拉起来.视图之间的轮转会变得跟加直接.当时想着Facebook的工程师们太高产了.

    这事就一直放着了,然后最近无意在微博上看到一个iOS开发者写的博客<iOS应用架构谈 组件化方案>突然想起之前那次闲聊时候的话题,引发了兴趣,随即把大神的几篇文章都读了一遍,感触颇深.起先写项目的时候从没考虑过架构的问题,就是那么写也没想着以后版本迁移,后续增加模块,觉得项目理所应当这么写.看过博主的文章之后,决定好好学习一下设计模式.

    以大神的一篇关于跳出面向对象的思想--继承这篇文章结合最近看的设计模式的书,简单梳理一下我的学习思路:
    首先是继承,用过的人多知道它有多好用,在基类里面做统一设置,所有的派生类再也不用谢重复的代码.光想想就是爽.可是,东西好用就有它的缺陷,它的缺点也暴露的很明显:高耦合.

    大神在他的博客中举了个简单的场景:产品经理提出一个需求,需要在首页,及其的他子页面写个搜索框.接到需求的程序员决定从之前写好的搜索框派生出一个新的:HOME_SEARCH_BAR派生出PAGE_SEARCH_BAR,目前就这么看,完全没有任何问题,

    需求增加,经理要求子页面的搜索需要多一个本地搜索的功能,于是你会在PAGE_SEARCH_BAR增加一个locasearch功能.之后变态的要求来了.经理提出来,把首页的搜索换一个样式,但是子页面的还保持原来的样子.这个需求看似简单,但是用继承的你确知道,有多蛋疼.首页你需要在基类的初始化里面写case,随着项目的进展,越来越多的子类,swich case大法慢慢写吧.

    然后别的地方需要用你写的localsearch功能,却发现需要把你所写的基类全部拿出来,如果你基类里面又引用了别的东西,只能呵呵.

    大神在他的博客给出的解决方案是:用组合替代继承。将Textfield和search模块拆开,然后通过定义好的接口进行交互,一般来说可以选择Delegate模式来交互。

    ,搜索框和搜索逻辑分别形成了两个不同的组件,分别在HOME_SEARCH_BAR,PAGE_SEARCH_BAR,LOCAL_SEARCH_BAR中以不同的形态组合而成。textField和SEARCH_LOGIC之间通过delegate的模式进行数据交互。 这样就解决了上面提到的两种类型的问题。

    刚好我在iOS设计模式里面也看到类似的做法,它取名叫桥接模式.

    举个列子:要模拟实现两个游戏机的操作,游戏机分别用AB代替.

    首先游戏机A和B都有左手边都有上下左右四个键位,右手边OX两个按键,中间是开始键位,其中A在右边还有一个选择键,B没有.除了键位有少许差别,面板操作几乎完全一样.如果你开始打算为每个具体游戏机设计专用的控制器,那么势必会有很多冗余.而且可能以后会导致子类游戏机的激增.以后的业务也许派生出来的子类可能不需要方向键,而是从加速到读取方向的变化,从而模拟上下左右.

    所以最好的做法是把虚拟的控制器和游戏机分离.这样他们就能独立的变化.从而不影响对方的代码.话句话来说,它们是有各自的类层次.两个层次会有不同的接口,通过对象组合的方法连接起来.它们之间的静态结构图是这样的:

    consoleVC(setCommand)----------->consoleEmulator(接受command)

    |                                                                                  |               

    |           A游戏机(接受command, 执行方法)          B游戏机(接受command,执行方法)

    |                          

    touchVC( [super setCommand]   上下左右选择开始OX)


    consoleVC和consoleEmulator分别是虚拟控制器和游戏机的抽象类,这两个类有不同的接口,在consoleVC中封装一个队Emulator的引用.consoleVC的实例可以在抽象层上是用Emulator的实例.这就完成了两个类的桥接.

    Emulator为其子类定制个性化接口,用于处理游戏机的底层指令.

    consoleVC有个相对底层的方法,向桥接端再发送基本命令,它的set方法接受预先设定好的command,并通过"接受command"把消息转发给内嵌的Emulator.

    指令集 模拟器基类 游戏机A,游戏机B和a类似,就不写了. 控制器.h 控制器.m

    我们想让所有的方法使用父类中的同一个setCommand实现,通过super 而不是self发送消息.通过桥接模式,可以看到组合对象的力量.我们为consoleEmulator实现的桥接不可能通过直接的继承来实现.

    这也是大神所提倡的优先使用对象组合的形式而不是继承.

    相关文章

      网友评论

          本文标题:设计模式的学习笔记

          本文链接:https://www.haomeiwen.com/subject/pfdhlttx.html