欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OOP/AD basic 博客分类: Design OOPUIOOXP设计模式 

程序员文章站 2024-03-19 10:34:16
...
OOP/AD basic
本文是为了配合庄子的论文,做一些OO的基础知识普及工作。
当然,即使是OO基础知识,我也不一定有足够的资格来普及,主要目的还是为了相互学习,共同进步。因此,为了便于读者找出漏洞,进行批评和抨击,帮助我进步,我尽量使用朴实无华,简单易懂的语言。用咱老百姓自己的话,讲述老百姓自己的故事。
为了突出重点,加强效果,文中不免矫枉过正,提出一些片面极端的看法。
为了方便起见,我也把Procedure Oriented称为PO。

1.代码重用
评价一门语言的重要标准之一,就是代码重用程度。PO的代码重用主要有两种方式:(1) 模块重用 Module Reuse (2) 模板重用Template Reuse

模块重用。比如,一个 a 模块,b调用a,c也调用a。这时候,a就是重用的。这种情况比较简单,PO已经做得非常好了,OO这方面没有什么太大的超越。

模板重用。一个处理流程的整个步骤都是固定的,就是其中一些部分是变化的。比如,在那个Design Pattern帖子里面。
http://forum.iteye.com/viewtopic.php?p=82944
那个排序的例子里面,sort算法是重用的,comparator是变化的。这个时候,sort就是一个模板template,comparator属于模板template中的变量。
OO在模板重用这个方面具有超越PO的语法优势。PO一般用Callback Function Pointer实现模板重用,而OO的Class内置支持this指针,具有了携带额外信息的能力。

2.OOP只是一种语法现象
PO如果要达到OO的效果,则需要用Struct + callback function pointer来模拟实现。C的语法记不清楚了,下面的代码就是一个示意。
struct  Comparator{
   void * info;
   int (*compare) (Runnable *  this,  Record a, Record b);  // compare is a function pointer
   // 注:具体的OO实现中,为了处理继承的多态,
   //虚函数指针不是直接放在这里,而是放在一个虚函数表
};

….

void sort(Record[] records,Comparator * comparator){ 
        for(int i =….){ 
                for(int j=….){ 
                        if(comparator->compare(comparator, records[i] > records[j]) > 0)
                                // swap records[i] and records[j] 
                } 
        } 
} 


如果要实现ReverseComparator,那么相当麻烦。

int reverseCompare(Runnable *  this,  Record a, Record b){
     Comparator* originalComparator = (Comparator *)this->info;

     return – originalComparator->compare(this, a, b);
}

….
Comparator field1Comparator;
… set up field1Comparator

Comparator reverseComparator;
reverseComparator.info = &field1Comparator;
reverseComparator.compare = reverseCompare;  // function pointer

sort(records, &reverseComparator); // reverse order


可以看到,PO实现高级的模板重用,不是不能做到,而是做起来非常麻烦。而OO语法内在就支持这种高级的模板重用。另外,OO语法的继承,对代码重用也有良好的效果,不过,目前继承好像有成为反模式的趋势,我就不多说了。怎么方便怎么用,代码简单,才是硬道理。

3.OOAD = Modeling
我同意庄子对“OO哲学”的批判意见。
OO书籍,我的观点是,只有OOP的经典书籍才值得细细研读。
大部分OOAD的方法论书籍,都在描述大而空的例子,而不是关注具体需求。

说实话,我们大部分人在做应用软件,而不是系统软件。处理的是业务的复杂度,而不是算法的难度。而大部分的OOAD方法论书籍,也是面向应用软件的。

如何处理业务的复杂度?无他,但手熟尔,全凭着行业经验的积累。一个不熟悉某个业务领域的程序员,要在两方面下功夫:(1)努力学习业务领域的知识 (2)努力提高业务建模能力。
如何提高业务建模能力?无他,但模仿尔,全凭着大师的经典著作。如Dlee推荐的《数据建模资源手册》,Martin Fowler写的《分析模式》等。这两本书讲述的都是需求中常见的业务模型,如人员组织,财务税务,生产销售,人力资源,等。
经典建模书籍,不可能包括所有的工作中需要的模型。碰到这种情况,一方面要尽量搜寻现有的经典案例,一方面要获取经典模型中的精髓,类推,举一反三,
在我看来,OOAD就是要积累这些数据建模知识,而不是学UML,也不是学哲学。当然,这只是囿于我目前的眼界和地位。
我希望将来有一天,我也能够达到这样的崇高的地位,靠谈论OO哲学过日子,而不是靠OO建模过日子。那意味着,我已经进入了制定规则的Top 10%, 脱离了开发工作的第一线了。
现在以我的程度,就开始依靠大谈OO哲学思想来获利,相当于*,脱离了现有生产力发展阶段的现实;是要遭到痛斥的,“你这个穷小子,想混进我们这个富人俱乐部,别做梦了。”

4.过程
个人偏见,我认为,OOA 就是 A for OOP,OOD就是D for OOP。分析设计的时候,即使不考虑具体实现细节,也至少要考虑到实现的可行性和难易程度。
CMM类的过程强调,分析设计的时候,千万不能考虑具体实现,一旦考虑了具体实现,不仅是乱了规矩,而且是落了下层。
相比于CMM,我有些倾向于XP的实现和分析设计交织的做法。
我表达过对“良好的设计从重构中产生”的怀疑。我觉得,重构不一定能够保证产生良好的设计,反而可能产生过度设计。这也许只是囿于个人眼界的偏见。这个问题在另外的帖子里面讨论过了,就不在此赘述。

我觉得比较好的过程是这样:
(1) UI 先行。先画出UI Mockup。对于Webapp来说,通常是HTML Prototype。
(2) 在此基础上,写出简单的用户操作手册。
(3) 一项项具体分析该系统实现中可能遇到的瓶颈,评估可行性,风险性,选择实现方案。
(4) 数据建模。
(5) 按照XP原则进入到开发阶段:测试先行,开发,重构,迭代,集成,迅速发布。这是目前我所知道的代码管理的最佳方案了。