• 2009-08-18

    《程序员修炼之道》 第五章 弯曲或折断 - [新知随笔]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://liuyangsl.blogbus.com/logs/44487455.html

    本章旨在探讨,怎样生产出灵活、柔软的程序。

    1. 解耦与得墨忒(tei)耳法则

    在使用对象内部的某个属性时,不要用贯穿的方法去直接读取,应该使用一个包装过的读取函数。

    得墨忒耳法则规定,某个对象中的任何方法内部,都应该只调用以下内容:
    <a> 它自身。
    <b> 传入该方法的任何参数,但不包括参数对象的属性。
    <c> 方法内部创建的任何对象。
    <d> 任何直接持有的组件对象,比如局部变量。

    虽然使用这种方法,可以有助于减少错误,便于维护,但是要编写大量的包装方法,产生额外的运行时代价。
    因此很多时候都需要在设计时平衡正反两方面的影响。
    反规范化:违反规范化原则,以换取速度。

    ---------------------------------------------------------------------------------------

    2. 元程序设计

    使用元数据进行动态配置:
    程序在运行时读取本地配置信息对自身的行为进行控制,而不要在编译时定义程序的动作。
    元数据用于描述应用程序的配置选项(如使用.ini文件对程序进行初始化)。

    元数据驱动
    代码中提供抽象的功能,元数据中定义程序的运行细节。(即代码中定义程序能做什么,元数据中定义程序怎么做。)
    <a> 迫使开发者进行解耦。
    <b> 迫使开发者推迟细节处理,专注于健壮、抽象的结构设计。
    <c> 不用重新编译,通过元数据就可以定制功能。

    商业逻辑:
    商业政策和规则更有可能发生变化,需要一种灵活的格式进行维护。
    使用元数据、小型语言、专家系统,都可以用于定义商业逻辑。

    ---------------------------------------------------------------------------------------

    3. 时间耦合

    程序运行中,有两个重要的时间概念:并发和次序
    在项目的设计阶段,人们的设计往往是线性的,先做这个,后做那个。
    我们应该容许并发,考虑解除任何时间或次序上的依赖。
    这样有助于减少项目开发过程中的任何时间依赖:工作流、架构、设计、部署。

    (1)工作流:
    借助UML活动流图,找出什么可以在同一时间发生,什么必须以严格的次序进行。

    (2)用服务进行设计:
    把功能理解为一个个独立的服务,这些服务位于定义良好、一致的接口后面,并发地处理事物逻辑。

    (3)为并发进行设计:
    对任何全局或静态变量加以保护,使其免予并发访问。
    设计更整洁的接口,以便于并发调用。

    (4)部署:
    一旦架构具有了并发的特性,那么部署就可以更加灵活多变了。

    ---------------------------------------------------------------------------------------

    4. 模型、视图、事件驱动

    把程序划分成模块,明确责任,有助于开发和维护,减少错误。
    模块之间的数据同步也需要进行严格的范围控制。

    (1)事件:
    使用事件,使对象之间的耦合尽量减少。
    事件触发者不需要了解接收者的情况,多个接收者互补干扰地处理各自的事务。

    (2)发布和订阅:
    发布/订阅协议可以准确的把事件发送给需要的对象。
    订阅方先向发布方注册,发布方一旦产生事件,就会按照名单来通知订阅者。

    (3)MVC模式
    <a> 数据模型:资源信息的数据格式。
    <b> 视图:数据的显示表现(图表、文字表格)。
    <c> 控制器:控制数据在视图中的显示逻辑(排序、缩放、等),并向模型提供新数据。既向模型,也向视图发布事件。

    利用事件驱动,我们可以把数据模型和视图,数据模型和控制器分离开来,从而实现更强大的灵活性。但是视图和控制器是具有耦合特性的。

    (4)模型──查看器网络
    在视图的上层再构建一个查看器,查看器可以有多种形式:报告脚本、视频字幕、动态网页等。
    查看器是抽象的,模型与查看器之间都用事件驱动。
    这样一个模型可以有多个视图和查看器,一个查看器也可以对应多个模型。

    虽然事件驱动可以解除一些耦合,但是监听者和事件发布者之间还是必须有一些相互了解,比如公共接口的定义。

    ---------------------------------------------------------------------------------------

    5. 黑板

    黑板系统完全解除了对象之间的耦合,提供一个“论坛”,知识消费者和生产者进行匿名、异步的交换数据。

    分布式类黑板系统:JavaSpaces和 T Spaces。
    以键值对模型为基础(元组空间)。

    这种系统可以在黑板上存储Java对象。通过字段匹配、子类型匹配进行查找。也可以订阅事件通知。

    黑板系统的基本特性:
    <a> 查找并获取数据对象。
    <b> 公布数据对象。
    <c> 取出并移除数据对象。
    <d> 当有制定数据对象写入时,通知订阅者。

    黑板系统的优点是,所有使用者与黑板之间,有单一、一致的接口。
    在很多应用中,各项工作的前后顺序可能不固定,就会出现许多种工作流。用黑板可以协调工作流,忽略前后顺序。


    收藏到:Del.icio.us