我们建立了3个数据库,这些数据库的操作应该如何处理,为所有这些操作导入Command模式么?
我们认为如果没有Undo,或者整体检查这类附加操作,那么Command模式并不比直接调用函数有价值,并且因为其必须纳入到某种类层次结构中(包含Execute()接口的虚基类以及具体的命令),这会导致类数目的膨胀,并产生不必要的复杂度。
因此在看不到需求的情形下:员工的增加、删除、修改、登记时间卡、登记销售凭条、登记协会服务费这些将直接用全局函数进行处理。这样既可以减少层次,也可以减少类的个数。
这里的决策和前一节的设计决策可以统一概括为后发制人,也就是说并不以灵活性的名义,预先为可能发生也可能不发生的事情买单,主要追求当前方案的最简单化。而支付这一行为本身,则不适合作为单独的全局函数,更适合使用命令模式。主要是因为支付需要进行统一记录,没有Command模式,会导致数据和动作的分离。
在Robert C·Martin的版本中,所有动作都是Command模式。我们来看一下调整雇员类属性时的方法。
这里的收益是ChangeEmployeeTransaction::Execute()中统一了属性变更的逻辑,付出是为了调整一些属性导入三层结构。这并不让人觉得是投入产出比很好的事情。因此我们会放弃这种做法,而是直接使用全局函数来处理这类动作。
是函数还是对象
如果对编程的发展历史做一个回顾,那么就会发现这样一条观点迁移的脉络:一切皆是函数→函数和对象混合→一切皆是对象。
在C的时代里,大多数人认为一切都是函数(最多使用一些抽象数据类型)。比如,C的标准库中提供的也只是函数。
面向对象兴起后,很多人则认为很多东西都是对象,但也还保持认为函数仍有存在的必要性。比如,在C++的标准模板库(STL)中,既提供容器类也提供算法函数。(www.xing528.com)
再到近来,认为一切都是对象的人越来越多。比如,在.NET的类库中已经基本上看不到全局的函数了。
但事实上这是一个尺度问题。
如果说表述现实世界同时需要动词和名词,并且动词并不总是从属于名词,那非强调一切皆是对象或者一切皆是函数应该就是偏颇的。我们来看一个最简单的例子。
有些算法是共通于很多容器类的,比如unique()。
为了实现这类算法时,大致有两种办法。
可以定义一组接口来定义这些算法的接口,并要求所有容器类从这些接口继承,并必须实现这些接口。
可以简单地把这些算法实现为函数,容器类则提供共通的基本操作,遍历,移除等。
如果遵循着一切都是对象的思路,那么就只能用前一种方法,但事实这样做一定会增加层次,而增加层次的根本原因很可能只是为了达成一切皆是对象的目标,并不十分有意义。
具体比较哪种方法更好是非常复杂的话题,这里不准备展开,唯一想强调的是后一种方法并非一无是处,C++STL的实现是一个例子,现在看来仍然非常经典。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。