《元素模式》读书笔记01

前言

最近业余在读《元素模式》这本书,英文原名为《Elemental Design Patterns》(书中将元素模式简称为EDP),作者为 Jason McC. Smith。了解这本书的契机是一次偶然在京东上浏览书籍,其相关推荐算法给我推荐了这本书。我了解 GoF 设计模式,却从未听说过元素模式。是中文翻译的问题么?翻译的这么玄乎,于是出于好奇心点开了链接。看完了简介和目录,仍然不明白。但书的编辑推荐让我下了决心购买下了这本书。

怎么理解“元素”?

在初中学化学的时候,我们接触了原子,译者这里翻译的元素,我把理解成化学中对应的原子,通常原子不可再分,具有极小的粒度性。而我们常见的 GoF 设计模式则是由元素模式组成的分子模式。或者从另外的一个角度来看,可以将元素理解为氢、氧、碳等基本的化学元素,而这些元素可以组成不同的化合物,化合物则类比于 GoF 设计模式。

设计模式是概念性的,它是一门基础科学,而元素模式则是这门科学的组成部分。

面向对象编程的四个要素

面向对象的程序设计可以仅用四个事物进行建模,作者将他们提炼概括为对象方法字段以及类型方法字段类型分别代表OOP程序设计中的三个基本元素:功能、数据存储和数据描述。而对象正是OOP的核心,如果失去了对象,其余三者则会走向面向过程程序设计。

这4个元素之间存在着许多关联。我们举个例子来看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Class2 {
func g() {
print("Class2 g()")
}
}

class Class1 {
func f() {
let obj2 = Class2()
obj2.g()
}
}

let obj1 = Class1()
obj1.f()

代码中隐藏着几点信息:

  1. 对象之间的相似度(obj1obj2
  2. 对象类型之间的相似度(Class1Class2
  3. 发起调用的方法(f())和被调用的方法(g())之间的相似度

整本书中作者提及了很多相似度的概念,指的是两事物之间相近程度。相对于文中描述的概念而言,相似和不相似,我们可以简单粗暴理解为相同和不相同。我觉得其实影响不大。

抛出这个示例,想说明什么呢?

元素模式是建立在设计空间的基础上的。设计空间的思个维度是对象、字段、方法、类型,他们按照状态划分真若干可区分的区间,形成一个超空间的坐标系。这个坐标系的二维和三维投影当然是可视化的,在二维或三维空间中,形成若干个相邻的方块。每个方块都有着明确的实际空间定位,代表着一种特定的元素。

从一个图开始

  • 集聚:同一个对象中不同的方法,涉及同一个对象和若干方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Class3 {
    func test1() {
    test2()
    test3()
    test4()
    }

    func test2() { }
    func test3() { }
    func test4() { }
    }
  • 递归:同一个对象调用同一个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 递归:相信大家都很熟悉了,举了斐波那契数列的例子
    class Class4 {
    func fibonacci(number: Int) -> Int {
    if (number == 1 || number == 0) {
    return number
    } else {
    return fibonacci(number - 1) + fibonacci(number - 2)
    }
    }
    }

    let obj4 = Class4()
    obj4.fibonacci(10)
  • 委托:一个对象的一个方法调用另一个对象的另一个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 委托:iOS中对于委托非常常见,比如各种delegate的形式
    class Class5 {
    func test5() {
    let obj2 = Class2()
    obj2.g()
    }

    func rock() {
    print("Let's rock!")
    }
    }
    let obj5 = Class5()
    obj5.test5()
  • 重定向:不同对象调用用一个方法(函数签名相似)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 重定向:调用另外的对象来完成和自己目的相同的工作
    // 接上面Class5的相关实现
    class Class6 {
    var obj5 = Class5()
    func rock() {
    obj5.rock()
    }
    }
    let obj6 = Class6()
    obj6.rock()

上图中的中间一列为当下研究的集中地,中间一行目前还不知道它们代表的意义。我们暂且删除它们,得到下图:

正如作者所讲,这些概念非常平凡,我们开发者天天都在本能的使用,但这正是它们的意义所在。将这些概念提炼出来,理解之后,便可用作设计的武器。

待续······

坚持原创技术分享,您的支持将鼓励我继续创作!