本帖最后由 swifter 于 2016-9-1 01:13 编辑





1、什么是设计模式

每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复的劳动。”
—— Christopher Alexander


我想告诉大家的是:

能看懂设计模式的代码,你往往只是懂了皮毛,设计模式真正教给你的是,告诉你的是什么是设计原则,针对哪种变化、哪种场景使用哪种设计模式。

现实中的场景不会让你在程序设计之初,一上来便套用设计模式,这往往十分不靠谱,更为实际的做法是,“Refactoring to Patterns”,结合你身边的代码,使用设计模式来重构代码。




2、分清设计模式与架构模式

刚开始接触编程的新人往往分不清什么是设计模式,什么是架构模式。甚至只知道架构模式,而不是设计模式,这里罗列出从低到高的三种关系。



2.1、设计习语Design Idioms

Design Idioms描述与特定编程语言相关的底层模式、技巧、惯用法。

(举个栗子来说的话,就像OC中的block,Swift中的函数编程、闭包、guard,不一一列举。)



2.2、设计模式Design Patterns

Design Patterns主要描述的是“类与相互通信的对象之间的组织关系,包括它们的角色、职责、协作方式等方面”。

(如Delegate。)



2.3、架构模式Architectural Patterns

Architectural Patterns描述系统中与基本结构组织关系密切的高层模式,包括子系统划分、职责、以及如何组织它们之间的关系规则。

(如MVVM、Redux、VIPPER、响应式Rx等等)




3、什么是GOF

设计模式的经典名著——Design Patterns: Elements ofReusable Object-Oriented Software,中译本名为《设计模式——可复用面向对象软件的基础》的四位作者Erich Gamma、Richard Helm、Ralph Johnson,以及John Vlissides,这四人常被称为Gang of Four,即四人组,简称GoF。

用Swift整理GOF设计模式(1)——扫盲设计模式 1

用Swift整理GOF设计模式(1)——扫盲设计模式 - 敏捷大拇指 - 用Swift整理GOF设计模式(1)——扫盲设计模式 1

Design Patterns: Elements ofReusable Object-Oriented Software

该书描绘了23种经典的设计模式,创立了模式在软件设计中的地位。通常所说的设计模式隐含地表示“面向对象设计模式”,但不并表示就是等于“面向对象设计模式”。




4、软件设计的复杂和解决途径

伴随着下面4个不可避免的变化(客户需求的变化、技术平台的变化 、开发团队的变化、市场环境的变化)。

那么我们又该如何解决复杂性?

  • 分解:人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂的问题分解为多个简单的问题;
  • 抽象:更高层次来讲,人们处理复杂性有一个通用的技术,即抽象。由于不能掌握全部复杂的对象,我们选择忽视它的非本质细节,而去处理泛化和理想化了的对象。





5、面向对象设计原则

设计模式的原则才是最重要的,而不像算法,可以去套用,衡量一个程序的好坏,需要我们来对照这些原则的尺子去一一丈量。

变化是复用的天敌。而设计模式的存在是抵御变化,但并不意味没有变化,而是将变化的范围逐步缩小。



5.1、依赖倒置原则(DIP)

  • 高层模块(稳定)不应该依赖于低层模块(变化),二者都依赖于抽象(稳定)
  • 抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)


下面为代码示例:

我们没有人是生而知之的,在了解是什么是抽象类之前,我们一定都写过这样的代码:

[Swift] 纯文本查看 复制代码
  class DrawingBoard{//绘画板,代表高层模块
        var lineArray:Array<Line>?
        var rectArray:Array<Rect>?
        func onPaint(){
            for lineInstance in lineArray{
                 event.Graphics.DrawLine(Pens.Red,
                  lineInstance.leftUp,
                  lineInstance.width,
                  lineInstance.height)
             }
            for rectInstance in rectArray{
                 event.Graphics.DrawRect(Pens.Red,
                  rectInstance.leftUp,
                  rectInstance.width,
                  rectInstance.height)
             }
         }

   }
  class Line{//底层模块(代表容易变化的模块)
       func Draw(){ ... }
   }
  class Rect{//底层模块(代表容易变化的模块)
        func Draw(){ ... }
   }


而这个设计原则告诉我们应该像这样去思考:

[Swift] 纯文本查看 复制代码
   class DrawingBoard{//绘画板,代表高层模块
        var shapeArray:Array<Shape>?
        func onPaint(){
             for shape in shapeArray{
                  shape.Draw();
             }
         }
   }
  protocol Shape{//抽象接口,同时也是一种稳定的模块(高层和低层都依赖抽象类)
        func Draw(){