从另一个角度看设计
真理可能在少数人一边。
---柏拉图
最初偏离真理毫厘,到头来就会谬之千里。
---亚里士多德
前面的章节中我们从一些正规的角度来阐述软件设计的基本思想原理,然而,如果我们被桎梏于这些所谓的规范化之中,那么我们的设计就黯然失色了,如果不采用另一只眼睛来观察,则永远不可能产生真正的突破。这一章我们就畅所欲言,从另外的角度来看设计。
1. 统一性
在物理学上,万物归一,就是统一成少数的一个或者几个原理,而这样的原理能够更好的驱动整个世界的运转,就如同有质量就有万有引力(或者是更深奥的有质量的物体下具有空间弯曲的广义相对论)一样,对于我们的设计来说,如果能够归于统一是一个非常棒的思路。例如:在我们的一个资费设计中,从业务上将我们存在试用和正式使用的两个状态,试用有时间限制和数量限制。而正式使用的根据费率的方式进行计时和计数进行处理。如果按照一般的设计,我们必然将之划分成两个状态。然后在程序或者数据库中进行区别对待。但是我们想一想,这样是否多余了呢?我们是否可以加之统一起来,我们将试用作为一个默认的处理,设置时间为1周,数量限制为2个。那么这个设置可作为数据库记录中的一个默认设置。这样我就不必进行什么特殊的类型甄别,试用和正式使用就只是数值上的区别,这样我的设计方案就大大简化了。
由于整个世界都趋于一个统一的特点,软件设计的过程中,亟待需要我们的系统能够进行统一化的方式来进行规划和设计。
例如,从计算机体系结构来说,最为简单的地址统一编码,就能够给我们带来十足的好处,可能基于不同的访问速度,不同硬件构造的设备,但是从抽象概念的地址方面,如果我们按照统一的地址进行编码,那么我们的软件系统就首先从这些繁杂的硬件特性中独立开来,在我们的软件系统中,不用体现这些地址上读写方式存在何种差异,软件系统的最为简要的统一性就获得体现。
在PWE3边到边伪线仿真中,IETF指定的PWE3的动机:
ü 通用标签,提供统一的数据传送平台
各种不同业务,如SDH/STM-N、ATM、IP网络基于包,传输时运营商希望这些业务均能以统一的方式汇聚,减少网络数量,配置维护的复杂度和链路的费用。
TDM采用固定带宽的时隙划分,它不支持突发数据业务的统计复用。
ATM技术,采用5字节头家48字节净荷固定长度的信元为基本传送单元,它除了ATM短信元带来的开销以外,还有ATM分拆和组装。(SAR)过程,特别是在高速率是非常困难,基于优化的PSN(分组交换网),这种网络应支持任意长度的网络流。具有执行优化的网络流量工程的能力,并对网络业务流具有分类,执行流量管理控制和按Qos优先等级的保障机制。
ü 仿真专线,提高高回报率的网络业务
尽管Internet业务是增长速度最快的业务,但它没有产生每比特最高的回报。对终端用户来说,专线价格虽然要贵过IP数据业务,但它有更好的业务质量和安全性的保证。
ü 数据感知,实现了不同数据业务的汇聚
数据业务的突发引起整个网络带宽的不足和对业务的Qos构成影响,必须要具有差异化,数据感知的另一个好处是业务在PE侧得到Qos的保障,在核心的IP/MPLS传送网络有专门的隧道,等于核心层通过PE侧知道了用户业务的质量要求,方便了端到端的业务和网络资源配置,大大简化了NGN网络的操作。
ü 保护投资,提供网络业务
PWE3提供了一个通用的封装层,使用PWE3+MPLS构建的网络,可以再新的2层封装新式的业务加入时无需对原有网络做任何改造,公用网络中已经安装巨大数量的传统设备,需要保留这些设备,并与之互连互通。
进行统一首先需要分离,虽然这看起来相矛盾的处理过程,其实并非矛盾,因为只有分离才能够进行统一,只有分离才能够更好的进行抽象,并将共通的东西独立出来,然后再规划统一的处理过程,所以,分离是统一的基础,在分离机制中比较详细的描述了分离的方式和方法,这里就不再赘述了。
一般的情况下,我们可以通过两种不同的抽象过程来达到统一的目的,这两种抽象过程称为“弱抽象”和“强抽象”,前者是从特殊到一般的抽象过程,也就是把一类具体事物或事物关系中的共性加以抽象概括的过程,后者是通过引入新特征而强化原结构的手续所完成的抽象过程,可以简单来说,前者就是我们常常看到的通过抽象的方式,将类事物的共有部分“抽离”出来,后者是通过“填补”的方式,引入新的特征方式,来达到整个系统的一致性的完备性。
第一种方式是常见的,只要我们采用抽象、比较转换的处理就能够更好的达到我们的预期的目标,但是这种方式往往容易因为一些特殊的反例而统一失败的情况。我们还是用编码的例子来说明特殊情况给我们带来的困惑,过去我们常常使用过的ASCII编码方式能够很好的描述英文字母以及字符,ASCII可以使用8位也就是1个字节完全进行描述,但是,当我们需要表达汉字、日语、韩文等形式情况下,我们需要进行扩展,于是就促成了UNICODE编码,UNICODE编码采用2个字节,能够覆盖几乎目前的语言字符,虽然从统一的场面来看已经非常完美了,但是,还存在一些特殊的字符(例如古汉语中的一些繁体字等)依然无法通过UNICODE来表示,但此时,如果再通过更多字节的扩展,其实我们的系统变得非常的生硬了,我们很难更好的进行“平滑的扩展”,注意这里的“平滑”的含义(我们至少在兼容性方式,继续扩展方面无法做到统一化的处理)。于是,为了更好的统一,就出现了一些中间格式的字符集,例如我们常常使用的UTF-8编码。
UTF-8编码规则:如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。
通过UTF-8进行编码,给我们带来了哪些好处呢?一方面是我们兼容ASCII,ASCII表示的信息好UFT-8在表示这个区域的字符是一个值。另一方面,我们可以按照统一规律将字符扩展到4字节、6字节或者更多的字节,而且这样的扩展也不需要重新打乱之前的编码序号,这样就通过规则的统一,达到一个更加“平滑”的兼容扩展。同时UTF-8编码可以通过屏蔽位和移位操作快速读写。
因此,大家是否看到,在进行统一化处理过程中,一方面需要及时发现这些反例,另一方面需要及时的考虑如何将这些反例融入到我们的统一化系统中,有时候,就是因为一个这样的反例就从某个角度上推翻了我们的统一化设计思路和方法,因此这对于我们将是十分宝贵的经验。
第二种抽象方式,其实要求我们进行一些适当的补充,而这些补充能够通过更加统一化的形式来进行处理,这样的处理方式很多,例如将指针进行迭代器的泛化处理等等,我们这里借用大师们的一个例子来说明这种统一化的方式的特点(通过定义NULL对象的方法来统一化我们的类体系)。
比如在一个系统中我们可以通过接口和组合模式来进行统一化的操作,如图7-2所示。
图7-2
但是,如果我们需要判断一个指针(引用)的时候,我们需要执行判断是否为空(NULL)的处理,此时如果我们增补这个NULL为一个NULL的类,将之统一到这个体系之中,那么我们的程序代码就能够更好的脱离具体的环境,能够更好的抽象并形成体系,如图7-3所示。
图7-3
这样我们就可以在NULL的重写接口的函数处理中进行我们认为非常合理的处理,然后非常美妙的达到我们的形式化的统一。所以这种抽象的方法要求我们自原有特性不足的情况下,能够根据进一步的扩展来划归到一个统一的形式化处理中,但是,这样的扩展也是有其条件和限制的,有很多时候,往往可能扩展不当而导致系统变得更加的非统一了,我想失败的情况肯定比成功的情况多得多,不然我们可以信手拈来就形成一个统一了,然而现实可能会更加“残酷”一些。
统一美揭示了系统的普遍联系上,美在我们对客观世界和谐协调、井然有序的真实反映上,从而使人们居高临下,揽括一切,增强了人们洞察世界的深广度,使人们获得更多的新成果,理解更多的新现象,对未知事物作出更可靠的预言,在改造世界中取得更大的胜利.追求统一美,必将促进软件设计的进一步发展。
由此统一性能够直接带给我们的是一种化繁为简的方案,这样的处理能够大大简化系统的复杂性,同时让理解和分析系统的其他人也能够非常简单的明白我们的系统,并且能够在这种统一的框架下进行更好的增量方式的开发和应用。
再回头看一下REST设计风格:
REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
REST设计准则:
ü 网络上的所有事物都被抽象为资源(resource)
ü 每个资源对应一个唯一的资源标识符(resource identifier)
ü 通过通用的连接器接口(generic connector interface)对资源进行操作。
ü 对资源的各种操作不会改变资源标识符。
ü 所有的操作都是无状态的(stateless)
原文地址:http://blog.51cto.com/13832308/2134695