Engineering

[Engineering] 设计模式奏鸣曲(二):描述与外在表现

2018-06-22  本文已影响26人  何幻

我们一般习惯从两个角度观察一个优雅的设计,
内在的,它的结构是否精巧,麻雀虽小五脏俱全,
外在的,它是怎样去周围的环境交互的,如何被使用

大部分介绍设计模式的文章,倾向于从实现角度介绍模式,
这是没有问题的。

但是,一篇文章一旦被写出来,就不得不为其写作目的服务,
要想鲜明的表达观点,就必须有所强调
所以,注重模式内在表现的文章,对于外在表现的阐述就不够了。

本文就试着消除这一盲区,从外在角度介绍一下设计模式。

字符描述

提到外在角度,大多数人可能还是比较陌生的,
因为程序员更容易站在代码作者的角度看待问题,
而不擅于考虑所提供的功能如何被使用

实际上,就像《计算机程序的构造与解释》所指明的那样,
代码只是计算过程的字符编码。

我们使用字符序列,描述了计算机内的运算过程,
继而,为了让这种描述方式更可靠
我们期望不同的运算过程,用不同的字符序列来表示。

字符序列与运算过程之前建立一种映射关系。
我们称,全体字符序列,构成了用来描述运算过程的语言
这些运算过程,给出了相应字符序列的解释语义

学习程序语言,就是学习语言语法语义的过程,
其中,语法指的是,构成语言的字符序列所满足的规则。

封装与接口

和硬件一样,软件系统也会将它的用户不关心之接口隐藏起来,
接口隔离原则就是这种思想的一种表现形式。

通过封装,于其内,减少了外部依赖和影响因素,内部就可以具有更大的灵活性更稳定,
于其外,减少了使用者的心智负担

这对外的表现,不经常被人提及。
只有把功能和功能的使用者放到一起才会看到这一点。

我们只是提供了功能,这没有价值,是有用户来使用它,才产生了价值。

因此,我们以后提到设计的时候,应该至少转换一个角度,
可以选择性的更多的关注用户的感受,以及用户与系统之间的交互过程,
这个用户,当然不一定是人,也可能是其他软件系统。

我们会发现,当我们从外在表现来审视一些设计模式的时候,
事情就会突然变得简单了很多。

设计模式的外在表现

让我们打开Gang of Four的经典教科书《设计模式》来看看,
先看第一个模式抽象工厂模式

该书采用了自己的一套对设计模式的描述方式,
每个模式都要介绍它的名字,意图,动机,适用性,结构,参与者,效果,实现,应用,等等方面。
我认为这是极好的,是一种系统化的思维方式

但是每个模式都这样介绍,就略显枯燥了。
我们应该学习的是这种系统化的思维方式,而不是具体它是怎么表述的。

另一方面,我想很多人一开始阅读也是很吃力,
这是因为,在书中很难直接找到某个设计模式的用例
对设计者来说,关心的更多是内部结构,但是对用户而言,则关心更多的是用例

让我们试着找出抽象工厂模式的用例吧,

MazeGame game;
BombedMazeFactory factory;

game.CreateMaze(factory);

就这么简短。

其中,CreateMaze接受一个MazeFactory类的引用作为参数,
BombedMazeFactoryMazeFactory类的子类。

所以,可想而知,CreateMaze并不知道传入的是哪个具体的factory
但是仍然可以使用MazeFactory中定义的那些方法,来创建迷宫(create maze)。

这就是抽象工厂的一个用例。
利用了面向对象编程中子类的多态性,增强了CreateMaze的灵活性,
解耦了CreateMaze与具体factory的依赖关系。

从用例角度来看,是不是更容易理解呢?
该书其他模式的外在表现(用例),感兴趣的朋友也可以试着找一下。

结语

本文从设计模式的外在表现(用例)这一角度,重新看待了模式问题,
并非想表达其内在结构是不重要的,
只是想转换一下角度看待问题。

电工在布线的时候,虽然讲究内部精巧,
但一到布线完成,墙壁粉刷之后,人们看到的将只会是线缆暴露出来的插台。
一座楼房,在建造之初,一定要稳定结构,打好地基,
但一到盖完之后,人们更多的只会在意它的外观,以及是否舒适。

确实是这个道理。

具有依存关系的两件事物,不可独立来看待。

以销售为例,只有你一个人是不可能做成买卖的,必须得有另一个人购买你所推销的东西。
—— 《人生定位

即便是最精美,最优雅的框架,可复用性最高的系统,
也必须有人来使用,才可能被复用。

所以,复用的关键是教学,而不是架构

Reuse is about people and education, not just architect.
—— 《软件架构师应该知道的97件事


参考

计算机程序的构造与解释
数理逻辑
计算机语言的形式语义
定位:争夺用户心智的战争
人生定位
软件架构师应该知道的97件事
设计模式
测试驱动开发
重构:改善既有代码的设计

上一篇 下一篇

猜你喜欢

热点阅读