2005-06-18
OOP/AD basic
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.javaeye.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的语法记不清楚了,下面的代码就是一个示意。
[code:1]
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]
}
}
}
[/code:1]
如果要实现ReverseComparator,那么相当麻烦。
[code:1]
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
[/code:1]
可以看到,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原则进入到开发阶段:测试先行,开发,重构,迭代,集成,迅速发布。这是目前我所知道的代码管理的最佳方案了。
本文是为了配合庄子的论文,做一些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.javaeye.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的语法记不清楚了,下面的代码就是一个示意。
[code:1]
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]
}
}
}
[/code:1]
如果要实现ReverseComparator,那么相当麻烦。
[code:1]
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
[/code:1]
可以看到,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原则进入到开发阶段:测试先行,开发,重构,迭代,集成,迅速发布。这是目前我所知道的代码管理的最佳方案了。
评论
flyingbug
2005-06-20
buaawhl 写道
而且,假如在理想状态下,开发者意识中的用户需求,能够固化,那么XP拥抱变化,也就没有了意义。
是啊,需求无法固化,这真的是个问题
但总要有一个统一的认识
这个问题我也一直很头疼
XP的拥抱变化是要付出代价的,而且有时候这个代价还不小
并不是所有的开发过程都可以去拥抱这个变化
还有一个问题就是XP的拥抱变化的方法也不是全部都普遍适用(有些还是很不错的)
buaawhl 写道
你这里的 系统的纵向设计 具体是指什么?是指架构分层设计?表现层、web层、业务层、O/R层?
架构的问题领域,非常确定,没有什么复杂度,也几乎没有什么变化。主要保证稳定性、灵活性、开发效率等。
关于纵向设计,你的理解是正确的,但不只分层
对于类MIS系统来说,我说的纵向就是分层
对于通讯基础中间件来说,主要是架构模型
对于ORB系统来说,还要有协作模型和识别及绑定机制
这些都是纵向问题,这些需要比OO更大粒度的东西支撑
架构的问题领域,并非非常确定,也不是没有什么复杂度
跳出类MIS系统,架构的重要性几乎决定项目的生死
partech
2005-06-20
buaawhl 写道
我觉得比较好的过程是这样:
(1) UI 先行。先画出UI Mockup。对于Webapp来说,通常是HTML Prototype。
(2) 在此基础上,写出简单的用户操作手册。
(3) 一项项具体分析该系统实现中可能遇到的瓶颈,评估可行性,风险性,选择实现方案。
(4) 数据建模。
(5) 按照XP原则进入到开发阶段:测试先行,开发,重构,迭代,集成,迅速发布。这是目前我所知道的代码管理的最佳方案了。
(1) UI 先行。先画出UI Mockup。对于Webapp来说,通常是HTML Prototype。
(2) 在此基础上,写出简单的用户操作手册。
(3) 一项项具体分析该系统实现中可能遇到的瓶颈,评估可行性,风险性,选择实现方案。
(4) 数据建模。
(5) 按照XP原则进入到开发阶段:测试先行,开发,重构,迭代,集成,迅速发布。这是目前我所知道的代码管理的最佳方案了。
到UI在某种程度上说已经是设计了。为啥放着XP中的用户故事不用?
用户故事只提供简要的目标,不会约束具体的实现方案。
用户手册还是快提交给客户时写比较好,因为在中间可能会变更,如果先写意味着返工。
你的实现方案都没有经过测试如何知道它确实可行? 基于评估的实现方案,是有风险的。
数据建模不是设计、实现的一部分吗?为什么需要先设计好哩?
buaawhl
2005-06-20
flyingbug 写道
先画UI的作用是为了固化和统一开发者意识中的用户需求(称之为用户操作接口)
无UI系统同有UI系统原理相同,先确定外部操作接口
这和我说的“开发人员根据这些UI进行需求理解,设计编码”,没有很大的区别吧。我不愿意重复这种司空见惯的常识和套话,尽量说一些我觉得大家不是很常见的一些说法。
而且,假如在理想状态下,开发者意识中的用户需求,能够固化,那么XP拥抱变化,也就没有了意义。
flyingbug 写道
OOA/D是横向的系统设计,它涉及到系统内部逻辑分配而已
它在系统的纵向设计上存在严重的盲点,
你这里的 系统的纵向设计 具体是指什么?是指架构分层设计?表现层、web层、业务层、O/R层?
架构的问题领域,非常确定,没有什么复杂度,也几乎没有什么变化。主要保证稳定性、灵活性、开发效率等。
OOAD确实不是做这些事情的。OOAD主要就是为了应对真实的业务逻辑的复杂性。应用系统之间的最大差别,就体现这个方面。应用系统决不是依靠架构取胜,而是依靠业务实现程度来取胜。而业务实现程度,主要依靠业务理解程度来保证的。
以前和一个朋友聊天,他说,以后他要开一个公司,专门为传统企业服务。他要雇佣那些厂子的退休职工作为名誉顾问,和程序员交流真实的业务需求。不用花很多钱,又能够充分发挥退休职工的余热,丰富他们的生活。我比较赞同他的这个想法。
flyingbug 写道
胖子最近在BJUG上讲的特征驱动设计在这方面似乎不错,不过我没去听,不知道他老人家具体讲了什么
BJUG上面没看到 o6z 的讲稿下载。
blog上也没有
http://ozagile.blogdriver.com/ozagile/index.html
flyingbug
2005-06-20
buaawhl 写道
flyingbug 写道
无聊看贴,八卦点评一下:
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
虽然一般的书籍都分为 OOD, OOA, 有需求分析,概要设计,详细设计,但我觉得(囿于自身的眼界精研所限),OOD/OOA 是一个东西,就是数据建模。OOAD = Modeling。产物就是DB Schema 和 基础类图。
先画UI,有点快速原型开发过程的遗迹。这个UI可以作为一个简单的Prototype, 或者说Demo。当然,这个UI不一定要运行。
快速原型要求作出一个可以简单运行的、将来要完全抛弃的demo。而这里的UI画好了,就作为将来的UI基准了。
我现在的工作流程就是这样的,Product Management Team画好了HTML UI,开发人员根据这些UI进行需求理解,设计编码。
先画UI,和OOAD的关系确实不大。只和OOA沾点边。要一个一个UI看过去,根据这些UI抽取出相同的功能模块,进行分析设计,这是Top-down的过程。真正设计编码的时候,按照bottom-up的过程,先实现基础公用组件,然后实现业务需求。
看起来,这有点和XP冲突,XP一般要求公用组件从重构中产生。其实也没有根本冲突,一开始尽量识别公用组件,重构的过程中一样可以产生公用组件。总之,公用组件越早产生越好。
实际的编码过程中,确实要和Product Management Team 或最终用户沟通,进行一些UI 操作和功能的调整,这都是难以避免的。XP直面这些变化,并很好的进行代码版本控制管理,可以说,解决了最关键的最棘手的问题。
无UI系统,一般应该是 Service Daemon之类的程序,这方面我没有很多的实际经验。如果没有UI,那么就省略画UI 和 操作手册 这一步。
老实说,我觉得你应该放弃在这个方向上的思考,试试去当一个技术支持人员
先画UI的作用是为了固化和统一开发者意识中的用户需求(称之为用户操作接口)
无UI系统同有UI系统原理相同,先确定外部操作接口
OOA/D是横向的系统设计,它涉及到系统内部逻辑分配而已
它在系统的纵向设计上存在严重的盲点,胖子最近在BJUG上讲的特征驱动设计在这方面似乎不错,不过我没去听,不知道他老人家具体讲了什么
buaawhl
2005-06-20
flyingbug 写道
无聊看贴,八卦点评一下:
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
虽然一般的书籍都分为 OOD, OOA, 有需求分析,概要设计,详细设计,但我觉得(囿于自身的眼界精研所限),OOD/OOA 是一个东西,就是数据建模。OOAD = Modeling。产物就是DB Schema 和 基础类图。
先画UI,有点快速原型开发过程的遗迹。这个UI可以作为一个简单的Prototype, 或者说Demo。当然,这个UI不一定要运行。
快速原型要求作出一个可以简单运行的、将来要完全抛弃的demo。而这里的UI画好了,就作为将来的UI基准了。
我现在的工作流程就是这样的,Product Management Team画好了HTML UI,开发人员根据这些UI进行需求理解,设计编码。
先画UI,和OOAD的关系确实不大。只和OOA沾点边。要一个一个UI看过去,根据这些UI抽取出相同的功能模块,进行分析设计,这是Top-down的过程。真正设计编码的时候,按照bottom-up的过程,先实现基础公用组件,然后实现业务需求。
看起来,这有点和XP冲突,XP一般要求公用组件从重构中产生。其实也没有根本冲突,一开始尽量识别公用组件,重构的过程中一样可以产生公用组件。总之,公用组件越早产生越好。
实际的编码过程中,确实要和Product Management Team 或最终用户沟通,进行一些UI 操作和功能的调整,这都是难以避免的。XP直面这些变化,并很好的进行代码版本控制管理,可以说,解决了最关键的最棘手的问题。
无UI系统,一般应该是 Service Daemon之类的程序,这方面我没有很多的实际经验。如果没有UI,那么就省略画UI 和 操作手册 这一步。
flyingbug
2005-06-20
无聊看贴,八卦点评一下:
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
只看到OOD没看到OOA
没有说清楚:先画UI为了什么?跟OOAD有什么关系?
简单问一句:无UI系统呢?
- 浏览: 585652 次
- 性别:

- 来自: china

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
网上银行的安全操作设计探 ...
有道理,不知道建设银行的UKey有啥用?
-- by sjz209 -
网上银行的安全操作设计探 ...
有道理,不知道建设银行的UKey有啥用?
-- by sjz209 -
网上银行的安全操作设计探 ...
1、据了解,动态口令采用的就是楼主说的第2种机制,所以动态口令发生器会有一个容错 ...
-- by jxb8901 -
谁说搞技术的没有幽默感?
yyliuliang 写道部门老大宣布放一年长假,大伙欢呼雀跃,连作三个俯卧撑表 ...
-- by hongfei3 -
谁说搞技术的没有幽默感?
幸存者 写道为什么我觉得不好笑?是因为我没有幽默感么? bingoo
-- by roger






评论排行榜