cast 的个人资料nonocast ! 真诚原是一种需要坚强不屈的...照片日志列表更多 工具 帮助

日志


6月10日

推卸责任也是一种责任

 
过去常常不理解Assert的用法,总是觉得有些鸡肋
用Assert的地方都是可以用Exception来替代,
but .NET依然保留,而Java 5中竟然加入了Assert
 
其实个人认为Assert的用意在于推诿责任,将异常处理交由最恰当的对象去处理
同时更为重要的是明确了处理这个异常不是我的责任
 
只有在职责明晰的情况下,才能做出正确的推卸,say no是有前提的
 
4月23日

单元测试的重要性

 
UnitTest不仅是对代码正确性的检验,更是在考验你的设计
每一个类处于不同的层次.平面上,拥有不同的职责
能相对独立的解决某一问题
是某个实体或行为或算法或业务或X的抽象
当然他有存在的上下文,要食人间烟火的,没有依赖关系就没有存在的必要
所以如何能让一个类在相对封闭的环境中进行**单元**测试是一个很大的课题
 
很多时候不是你不想做单元测试,而是你的设计导致你根本无法下手做单元测试
心有余而力不从
你不妨随意瞄一眼你现在IDE中正在Edit的类,他能进行单元测试吗?
 
一个好的对象设计应该很容易为他的每个单元进行测试
其实这一点可以上升到对一个设计的评价尺度上
 
所以在设计的同时多考虑一下单元测试是一个设计师的职责
对异常以及错误上的探索也同样属于设计师的职责
 
这个在编写有效用例中已经大下笔墨的问题也无需再提及
实践证明,对一个类是否能测试以及对错误的管理不是编码中可以轻易重构的
重构不要成为设计推卸责任的借口
其实在细节的把握往往成为决定胜负手的一个关键
随着长期的实践,我们才会渐渐有信心写出让人让自己放心的软件
 
11月23日

Behavior First!

 
过去以为类是整个面向对象模型的核心,很自然的让人联想到类的结构,把大量的功夫都耗费在建立一个完整的类模型,面对问题上来就是拆解结构,
电脑,电脑由显示器,机箱组成,机箱又有主板,芯片,电源,插槽,内存,硬盘....组成。

然后提出'设备'这样一个抽象类,全部从此派生,多么美妙的对象模型啊!

Oops,如果你正在写一个程序,希望它能让他做点什么的话...其实你知道,本质是行为,而不是结构,没有行为,即使你对整个宇宙建立模型,也不能解决任何问题。
 
我想说的也正是这个,软件的本质是行为,它能做什么,而一切一切的结构都是在为行为服务。

So, Behavior First!
 
好的结构只是一个好的行为必然的伴随物罢了,不要把设计一个好的静态模型作为最大的靶子,那你就失去了系统本身最重要的意义。

 
11月21日

Interface Vs Abstract Class

 
个人认为两者是完全不同的两个概念
inferface专注于概念层的抽象
而abstract class专注于解决实现层的抽象
 
比较来说,就是他们抽象的层面不同
这也同时体现在建模过程中
过程应该是,
interface + class > concrete class > abstract class
 
从具体类到抽象类的过程类似于提取公因式,说白了就是为了少些代码罢了,当然还有其他作用,比如多态
而interface才是整个领域的起点,目的是抽象概念,来表示系统中概念的消息以及协议
interface应该依赖于interface
当然概念并不是只有interface来表现的,对于那种相对稳定的概念应该直接使用class
过多的interface同样不是一个好的设计
 
设计时需要对系统的变化进行管理,什么是最易变的,什么是最有可能被扩展的,当然也要把那种maybe,perhaps尽早扼杀掉
否则成本....
 
总结一下,interface是抽象的,abstarct class是具体的,这里的抽象和具体是相对于两者的,呵呵
BTW:抽象类之所以叫抽象类就是表明了在类层次中的抽象,而interface则是在领域中进行抽象
把层次分清楚就容易辨识这两个看似功能很像的概念
 
8月27日

概念惯性

需求如下(非常简单),

为一个学校提供课程计划任务的打印功能,打印出来的数据就是

XX系XX专业XX年级   于   XX学期(大学4年8个学期)    开设   XX课

 

那么首先就要对系,专业,年级,课建立相应的对象,如图,

 

这样很容易理解,

年级: 外语系英语专业02级

课程: 计算机系软件专业汇编原理

然后课程任务就是,

外语系英语专业02级02级于第一学年第一学期开设外语系英语专业英语口语1课程

 

到这里都ok,现在的问题是如何处理公共课这样一个概念(其实大家对这个应该都是有实际概念的),

大学英语是一门全校性公共课,虽归属于外语系门下,但并不属于其中的任何专业,这样一来就打破了一致性。

那怎么把这个概念融合到上面的设计中去呢?

不知道你是怎么考虑的,呵呵,不妨在纸上涂上两笔,看看有没有什么思路。

 

在我起初的考虑中,并没有太重视这个问题,只是通过在系下面加入一个特殊的专业--公共专业来考虑,这样一来保持了上面那个结构,

在实际操作中,这个设计上的小问题通过VO层,表现层逐步被放大,要知道这本身就是一个很mini的项目。

其实前面还存在一条非常明显的路,就是在专业上面加一个bool值以区分这个是否是公共专业,我个人认为是不可取的,为什么呢?

因为在领域这个层面上,不应该过早带入语法层面的判断,这样破坏整体感,实际操作上也很难区分是领域判断还是技术细节判断。

还有另一种观点,那就是把这个bool值加在课程上面,用以区别公共课还是专业课,除了上面说的过早带入了语法判断以外,还有一个问题就是

把不属于课程本身的东西带到课程中去。


举个可能不太恰当的例子,

你有很多衣服,你对每一件衣服都有不同的喜欢程度,从0-100,你是否认为这个值应该放在衣服对象上?

 

所以最后我得去的设计如下图,

 

从另一个角度来说,设计本身不存在一个唯一的正确答案,在不同的情形下有属于他们自己最适合的设计。

从前后两个设计来说,区别点也就在于多了一个类,但这一步是很难迈出去的,从一个角度来说,对于类直接的关系,领域内的问题就应该通过

他们的形式规则来解决,不需要语法层面的介入,其二,设计也是不断迭代的过程,你的设计能够抗的起领域对象的变化吗?

 

BTW:最后再对一些细节问题做一些补充,

你知道的,人的容错性是非常大的,当我们说软件专业我们可能理解的方式是非常多的,但要让程序的容错性增大无疑需要大大增大程序本身的

复杂度,结构上的复杂和一些冗余的目的就在于排除二义性,因为他毕竟不是人,我也没有能力给他加入人的智慧,说到底,我比较懒。

7月30日

变化中出对象

过去一直以为抽象是面向对象中举重轻重的词语,后来才慢慢发现还存在一个更为重要的词语
 
变化
 
其实在explain DP中就反复强调这个词语,但我一直没吃透,我一直很难理解什么样的设计才能应对变化,一个抽象度相对高阶的设计可以应对更多的变化,容纳更复杂的结构。
但后来我也发现要在设计完后应对变化就如同让程序在能自动解决Exception一样,或者说更为复杂,其实我们更多需要应对的变化是在编码前以及编码时,是根据需求作出恰当灵活性,将变化列入设计内,而后根据恰当的灵活和变化才可以作出恰当的抽象用以搭建对象体系,否则的话抽象的标准是什么呢?
7月28日

Decorate or Strategy

Decorate Style

BlockDataSource = new BlockDateOrderFilter(

       new BlockDataSource(

              new SpecifyDateRangeEntryVODataSourceFilter(

                   new SpecifyUserEntryVODataSourceFilter(

                       new EntryVODataSource(SpringContext.getManagerFactory().getEntryManager()),

                       SpecifyUser

                   ),

                   new Today()

              )

       ),

       true

);

 

Strategy Style

BlockDataSource = new BlockDataSource(

       new EntryVODataSource(

              SpringContext.getManagerFactory().getEntryManager()

              new SpecifyUser(SpecifyUser),

              new Today(),

       ),

       true

);

 

 

从直觉上来说,上面显得更松,更易于测试。

问题在于对于FindAll这种Filter来说,N个Filter,复杂度就是N倍,我想这是一定不可以的

理性告诉我应该使用Strategy,但GOF上所举的Stream Decorate例子抑或JavaI/O一再用Decorate来对Stream Wrapper,复杂度同样也是N倍!

 

最后根据以下原则再次作出一个平衡

 

用一个Decorate你可以改变对象的外表,而Strategy使得你可以改变对象的内核。

 

如果以外表和内核来区分 Decorate or Strategy,抓住两者的动机,我想应该是下面这样的结果,
 

BlockDataSource = new BlockDateOrderFilter(

       new BlockDataSource(

              new EntryVODataSource(

                     SpringContext.getManagerFactory().getEntryManager()

                     new SpecifyUser(SpecifyUser),

                     new Today(),

              )

       ),

       true

);

 

这里的排序功能以Decorate出现,而其他的作为Strategy,没有增加任何复杂度,

换句话说在不增加复杂度的情况下更倾向于Decorate。

再次体会模式本无所谓模式,是一个代码演化的过程,思想演化的自然过程,领会对象意图,抓住基本概念,结合具体问题作出恰当的选择折中和平衡,这可能就是最大的挑战!Fighting..YO

7月10日

面向对象软件是对象的社区

面向对象软件是对象的社区。社区重的每个居民都为其指定的邻居提供细细和服务。设计构造精良的写作模式是任何对象设计的核心。

对象层面上的异常

<< object design


带入

结构工程师和历史学家Henry Petroski在谈到了解失败后果的必要性时说,"在核电站的设计过程中,结构上的失败其后果是致命的,因此核电站的设计过程包括了相当数目的冗余结构设置,也保留了相当大的安全余地。而在另一种极端情况下,某些脆弱的结构,如鞋带,灯泡等等,他们结构上的失败并不会带来多大的影响,因为他们都是便宜的物品,为了平衡成本,采用脆弱的结构是合理的。然而在这两种极端情况之间,大多数结构设计选择都不是显而易见的。没有设计者希望设计的结构是容易崩溃的,但是他们却又部位安全性考虑而做特别的结构设计。设计者、客户以及用户不可避免的要面临诸如,"到底多少冗余设置才是安全的?","所允许的最大开销是多少"等令人不快的问题。作为软件设计者,必须让设计的软件机制能够达到预期的效果。

 

信任域
处理如何增强协作的一种方式是将软件分为几个可信任通信发生的区域。一般而言,在同一个信任域中的对象彼此是可以互相信任的...
针对不同的信任采取相应的设计方式,而决非Runtime处理。

异常错误
错误是由一些畸形的数据,坏的程序或是换掉的硬件所导致。在错误的层面上,基本无法采取任何有效的措施。除非软件本身有特别的需求,否则不应该花费大量时间来设计错误修复。
...然而出现异常却是正常现象,不过一旦异常发生,软件有应该,有职责进行处理。

 

对象异常用例异常
本质的不同。
用例异常反映的是参与者或系统无能力继续其任务的情形。
对象异常反映的是对象无能力处理一条请求。


对象异常
程序必须能力处理异常。明确的列出可能破坏程序的所有情况是一条较好的设计规则。
                                                                                                                                 --- Jorgen Knudsen

 

你要知道,任何一个很正常的异常如果没有得到适当的处理,会导致整个系统的失败,就如不可处理的错误一般。这样的事情决不应该发生!

抛出异常就是一个寻求写作的过程,(如果你都能处理又何必抛出异常?!),其中包括抛出异常的对象,发送了引起异常请求的客户以及协作链上的一个或多个对象。

担任异常处理责任的对象要采取有效的处理就必须有足够的信息支持。

异常对象是一种信息持有者。

一些指导方针,
1.避免设计太多的异常类。
 为保证异常处理代码的简单性,要尽量上的定义异常类并基于异常对象的值来设计客户端的不同反应。
 设计异常类与普通类的方式是一样的,其基础还是职责与协作。
2.以发生异常的事物而非抛出异常的类来命名异常类。
3.当提升抽象层次时,要将低层异常转型为高层异常。
4.异常中封装上下文背景。
5.将异常处理职责指派给做决策的对象。
6.尽可能地在离异常发生最近的地方处理异常。
7.考虑返回结果而非抛出异常。


 

讨论interface在java编程中的作用 [Part.2]

said,

这篇文章非常重要,列位看官,打起精神了!

1
、为什么要OO,这是第一个问题,原本数据和程序是分离的,导致大量的问题,因此通过面向对象的方式,将数据和处理数据的程序,封装在一起,这就是面向 对象的基本动力。当然,这样的封装带来了很多麻烦的问题。(下一篇文章,我会讲讲,数据与程序各自继承,然后灵活封装的一些思路。)但是好处还是很多的。

2
、封装,可以有一个很直观的理解,一个对象有了外部和内部,使用者只能看到一个对象的外部,而内部的数据和程序则是不可见的。我们可以打一个形象的比 喻,一个对象是一个三维实体,而它的接口,就是一个二维的表面。一个class,就完全的具足了三个概念数据、程序、接口。如果不是为了 开发大规模的程序,仅仅有class,就足够了。

3
、共享->继承。继承的概念来自于共享,作为一个独立存在的对象,每个对象之间都是有差别的,如果没有继承的概念,那么就会需要写很多重 复的代码。而通过继承,我们可以做到:“AB的共性的部分,我们抽取出来,先做一个基类。然后让AB在继承之后各自扩展它。

4
、实例->abstract class。因为所有的class都只是模板,真正有意义的是class的实例,因此,多个对象的共性部分,也许并不够资格成为一个真正的对象的模板,因此,出现了abstract class的需要。

重申一遍:只有当多个对象所要继承的公共基类不能被实例化是,才需要abstract class。也就是说,如果这个公共基类可以被实例化,我们不该用abstract class,如果只有一个对象来扩展这个abstract class,那么这个abstract class也是多余的。

5
、抽象类的形象比喻。抽象类其实应该称之为不完整类,从几何的比喻来说,它同样是三维的,同样有外部、内部的区别。唯一的不同是不能通过它得到一个实例。

6
、二维表面->接口。interface与类、抽象类的最大的区别,它不是一个三维实体,它没有外部、内部之分。因此,千万不要将interface理解为抽象类的进一步抽象。作为一个二维表面,它的最大的作用不是实现多重继承。再重申一遍java从来就没有提供过多重继承interface最大的作用,是提供对于一个类的多种可能的视角。

你将一个classimplements部分去掉,大多数类都照样可以编译,这个类的功能也同样没有减少,唯一的区别是:按照那些接口来使用 这个类的用户会报错。因此,相对于多重继承的加法interface不是,也不可能给一个class带来新的实质内容,而只是提供了多重的视角。

7
、因此,结论如下:
A
、如果你定义的一个interface没有给一个class带来新的视角,那么这个interface就是浪费。
B
、如果你想实现多态,那么你应该使用abstract class,而不应该使用interface。因为他们语义不同。哪怕是一个纯抽象的抽象类,也不能等于interface
C
、所有的语言元素都是因为需要而产生的,但是你总是可以误用他。

 

 

ajoo 反驳到,

引用: interface最大的作用,是提供对于一个类的多种可能的视角

 

我不认同这个说法。

你还是在围绕着你的"class implements interface"的视角说话。而这在interface的使用中属于次要地位。

为什么你不肯看看"declare requirements as interface and use interface directly"这样一个即声明即用的模式呢?



"implements SomeInterface"
虽然是必要的,但是毕竟仍然是用来建立类和接口的关系的。也就是说,仍然是和实现细节相关的,模块内部的东西。

在另一篇帖子里我就曾经强调过,一个类implements一个接口还是同时implements两个接口,对于结构设计来说,并不重要,只不过是类内部的实现细节。


interface
的作用在于把规范,协议这些东西作为first-class的类型使用。它唯一的作用就是帮你解耦。

类型分开来看待。

interface
的最大作用,不在于可以给提供什么东西,而是在于可以让你忘掉,忘掉实现,直接面对规范,协议。


简要地说:interface的重要性在于它本身的抽象性。而不在于"implements"这个keyword

凡是谈到和相关的任何东西,都不是最重要的。


另外,说如果没有继承的概念,那么就会需要写很多重复的代码,我也是不同意的。不用继承,用接口组合,也可以达到类似的功能的。而且更灵活。

 


引用: 只是声名一个interface,而没有一个(哪怕是一个MOCK)对象来实现它,你是不可能真正开始使用你的类的

 

这话没错是没错(当然,还得看你怎么定义"使用"这个词.没有实现类,我也可以写我的接口的使用类)

但是,有什么意义呢? 没有main(),你的所有的类都不可能最终运行,那么难道我们说什么设计都要扯到main()
?

人不吃饭都得饿死,难道我们讨论编程的时候能说oo的主要方面在于吃饭
?

即声明即用意义何在?

我上星期写了一个检测输入错误的模块. 我自己定义了接口StringMap来表示外界的输入(很可能从HttpServletRequest). 我完成了代码. 编译通过. 然后自己用HashMapadapt出来一个StringMap来单元测试. 代码测试完成后. 交给别人, 别人只要把HttpServletRequest adaptStringMap就成了.

 

 

 

我理解的老庄的意思,

第一层:接口是用来实现的。

对这个用法,我同意老庄的观点,它不是必要的。本来类就已经是实现了,为什么还多加个接口?脱裤子放屁嘛!

第二层:接口是用来给类来提供一个视图的。
这个方法,在我的总结,主要作用就是封装。你可以进一步把一些实现细节封装在类内部。然后给外部一个最小的视图。
我的静态工厂的目的就是这个。
但是,我仍然同意它不一定是必要的。我的经验是,如果一个类要做成public的,漏到package外面,就考虑让它实现一个接口,隐藏构造函数,然后用静态工厂公开语义入口。这种api式的设计方式可以保证包内部的实现变化最小程度地影响包外面广大的用户。
至于包内部的东西,就不见的有这个必要。毕竟这种设计是有额外代价的。

第三层:接口是用来给类提供多于一个得视图的。
我对这个不以为然。一个类有几个视图并不重要。用户看见的只是一个一个的视图,谁管它们是不是同一个类的视图?当用户看见的是视图,具体类对他们已经毫无意义了。

而我的看法:接口是用来让你忘掉类而直接面对规范和协议的。

讨论interface在java编程中的作用 [Part.1]

 >> http://forum.javaeye.com/viewtopic.php?t=7776

 

 ...

 

ajoo said:

老庄:

我觉得可能是我的表达太过二义性了。造成你的理解和我说的意思不大对的上茬。

你看我最后回复的那篇了吗?你的思路始终还是在实现者定义接口这个基础上。

而我前面反驳你的论点,都是基于使用者定义接口这个前提。

 

.所谓接口是你自己定义的。反映你自己的需求。什么叫没有完成?这句话说得不清楚,也难怪你不明白。

举个例子,我要实现一个功能A, 在实 现过程中,我发现我需要调用一个功能跟我自己正交的模块B

此时,我第一步要作的就是,总结我对模块B的需求, 对吗?

怎么总结? 通过接口。我自己定义出模块B要给我提供的接口IB以及相关的语义。

然后,把IB ioc进来,直接就用了。

这个IB是否一定对应"class B implements IB" 我不知道,我也不关心。

 

这里,我实现我自己的A的时候,可能已经有了接口IA,也可能没有。但是,无论如何我定义了接口IB

 

 

.关于单元测试,单独测试A,单独测试B, 联合测试A+B。都是少不了的。

不过,如果之间不是用接口耦合,你就只能联合测试了。我个人是认为单元测试是不可省略的。

我不希望A的作者有借口说我不能测试,因为B还没测完呢。

 

你的思路更象是造房子,地基打好之前别的都得等着,房子没造出来,屋内装修也是痴人说梦。 我的思路则象是计算机内部得各种插件。给每个插件定义好如何和别人联系的接口插槽,然后大家自己干自己的,互相之间不需要有其它依赖了。

 

.你的例子还是围绕在实现功能A, 是否要先定义接口IA上。我对这个问题的回答是:不一定。看程序员自己了。

 

但是,我说得免费的情况是指需求者定义接口这种用法。也就是,实现功能A,发现需要功能B, 那么不要费神去找实现了B的类,直接就定义接口IB给自己用。工作量是不是最小?

 

 

忽然想起一个问题。不知道大家在写业务层,持久层,物理层的时候,是否让业务层直接依赖持久层的类,持久层直接依赖物理层的类?

这就是一种建造金字塔一样的方法。要测试业务层?必须等物理层写完了,并且测试好了,然后持久层写完了,测试好了,才能开始。

 

要是想从jdbc basedxml based的物理层迁移,整个金字塔就得重建。

 

相反,如果业务层依赖的仅仅是抽象的持久层的接口,持久层依赖的是物理层的接口。那么,迁移物理层,其它层并不需要动。

 

点菜式的使用者定义接口的方式,业务层的接口是用户下的菜单。

持久层的接口是业务层实现者下的菜单。物理层的接口是由持久层实现者下的单。

 

实际上,如果面向接口,这个分层都不是绝对的。

 

对业务层的客户,我看见的是业务层的接口,你如果kiss,可以不搞那么多层,直接用jdbc实现业务层,并不影响我。

 

对持久层的客户(主要也就是业务层了),也是一样,我看见的就是接口,你的实现是通过调用间接的物理层还是直接用jaxp apixml与我无干。要kisskiss好了。

 

这才体现出面向接口的好处。它给kiss提供了最大的可能。

 

 

嘿嘿,top down, bottom-up

我前几天还在感慨fpl里面隐含着的bottom-up的思维方式和oo里面鼓励的top-down的区别,马上在oo里面看到这两个家伙又打起来了。

 

要我说,interface的一个好处是,它让你不用严格top-down,也不用彻底bottom-up

interface,你可以在问题的随便挑一个感兴趣的层次开始考虑。比如,我这人不懂业务逻辑,从top-down开始搞业务层比较麻烦。

我也不会jdbc,从物理层开始bottom-up也不可行。

 

没关系,用接口,我把两边都抽象起来,把问题拦腰一切,从中间开始着手做持久层。

 

你说这是top-down还是bottom-up呢?

 

这其实更符合人的思维方式的。

比如说,公司里,多数人都不会象总经理那样需要高瞻远瞩,运筹帷幄,但是也不是所有人都了解最基层的每个公司运营的细节。

但是,不妨碍每个人在自己的职责范围内给公司做出贡献。

 

公司可以换总经理,可以换底层的程序员,换了谁,公司都照样运行。为什么?就是因为这些上层啦,下层啦,都是按照一定的协议互相合作,并不是固定地依赖某个人。其实,所谓上层下层,主要是一种谁服从谁的行政关系(在oo里就是谁调用谁以及各个调用的语义),结构上只是各有分工,并不一定是严格的层次结构。

 

孔子说得好:只有分工不同,没有高低贵贱。

 

夫子真是大师啊。几万年前就把oo理论深入浅出地谆谆教导给了子孙。可惜我们这些不肖后代居然把淀积深厚的文化精华弃如敝履,反而去追捧浅薄的洋鬼子们的几孔之见。真是羞见夫子于地下呀。

7月1日

站在对象的角度上看测试,日志,持久化和错误机制

我们说要做一个好的OO设计需要Thinking in OO
but 即使全副OO思想,问题在于你没有很好的Coding功底
一切还是浮云
对象给人一个很曼妙的幻想,使人孜孜不倦
我们关注了对象的职责,对象的设计,从对具体到抽象,最好去除所有的coupling
有时候会被单元测试,Spring,Hibernate带
都不知道自己在哪着走
 
难倒不觉得有点smell吗?
 
停下来,回到原点上,我们的目的是写出更优秀的代码
而不在乎是否使用了Spring,Hibernate,又或是TDD
问题在于我们观察的角度
 
如果OO可以让你很轻松的构建出一个Domain,但你的Domain又是否真的准备好了呢?
是否为每个对象准备了测试,书写了日志,以及设计了错误机制呢?
 
这些活是逃避不了的,勇士,站直了去面对,去战斗吧!
6月29日

迟到的测试

namespace UnitTests {

         public interface IPerson {

                   string Name { get;}

         }

 

         public class Hello {

                   IPerson person;

 

                   public Hello(IPerson person) {

                            this.person = person;

                   }

 

                   public String Greet() {

                            return "Hello " + person.Name;

                   }

         }

 

         [TestFixture]

         public class GreetTest {

                   private Mockery mocks;

                   private IPerson mockPerson;

                   private Hello hello;

 

                   [SetUp]

                   public void setUp() {

                            mocks = new Mockery();

                            mockPerson = mocks.NewMock<IPerson>();

                            hello = new Hello(mockPerson);

                   }

 

                   [Test]

                   public void test() {

                            Expect.Once.On(mockPerson).GetProperty("Name").Will(Return.Value("nonocast"));

                            Assert.AreEqual("Hello nonocast", hello.Greet());

                           

                            mocks.VerifyAllExpectationsHaveBeenMet();

                   }

         }

}

 

6月28日

请记住抽象的定义...

放大本质部分,除去无关紧要部分。
 
                                                                     ---- p174, ASD, Uncle Bob
3月28日

reuse

我们现在可以有很多组件拿来复用,有很多类拿来复用,希望拖拖控件就搞定一切
 
在oo的世界里,最大的复用度级别是思想的复用
 
模式在一定程度上也欺骗了很多人,认为有模式就ok,其实真正的人懂思想,其次才是懂模式
 
所以我要推荐分析模型,这就是思想上的复用的结晶,当然他也只是冰上露一小角。虽然有些晦涩,但不失为思想集。
还有就是uncle bob的几本书,就不介绍了吧
2月27日

MethodMissiing

对于ruby的MethodMissing
这一下子就打破原有在C++/Java之上对对象的概念,

大凡OO理论都会腔调Message和Method之间的不同
但落实到具体,尤其是在强类型语言中message最终还是以method出现
太可怕了

要知道message和method概念上是有本质上区别的

就像一个人一样,是一个对象你在他1岁的时候给他一个脱衣服的概念,他懂个P啊,但随着长大就会了,但大到一定年纪以后上了岁数,自己知道怎么做却已经做不了了,这是同一个对象在不同时期对同一消息作出的不同反应。
其二我对一块石头大声说你TMD给我脱衣服,可能我出于某种情绪的发泄,别想歪,但绝对不应该限制我给石头发消息的权利,当然石头是完全不会睬我的。

我个人觉得很多人对 对象,面向对象的概念还是很不了解的。

以为
XXX.yyy()
这种形式就是OO了。

对于ruby中的消息在没有参数的时候是可以省略括号的,当然也完全可以在有参数的时候省略括号

puts "nonocast"

但这个时候就会有一个误区,不是ruby的错哦
比如说你看到
MyClass.options

如果仅凭这句你觉得options是一个消息呢?还是一个属性呢?
嘿嘿
这其实是一个挺重要的概念。

为什么只能def MethodMissing
而却没有def AttrMssing呢?

以对象的观点来说,对象应该只能接收Message,就像你自己知道23岁,别人要用的时候都是要问你小Y你几岁,你回答23这样子一个过程吧

他有什么权利直接用你的属性不是吗?
2月16日

面向对象模型之所以难在于动态平衡

对象模型本身的难点不在得到对象
而是抽象程度的拿捏把握
是否要抽象,抽象到什么程度?
这个很难有一个标准,都是视情况而定的。
这是一个典型的balance。
第一步就要认识到这是一个balance,呵呵
1月20日

下一眼

我们总说一俊遮百丑
但工程就是工程,不是一个方法就能解决所有问题
就像OO本身不能对软件的robust有所帮助
所以下一步将在robust上下一番功夫
 
最近在看robust java,think in java.etc
一直想看code complete,但还没机会
总是感觉这块是一个软肋,把握的不好
如何能有一套机制来控制OO,辅助OO这是现在的当务之急
 
很多内容都是在将如何使用exception,但真正说如何用的,介绍经验的缺又很少
hibernate从2.1到3.0很大的一个变化就体现在exception从checked到unchecked
看来这个问题不是那么容易解决的,或者说又是一次博弈
 
不管怎么说,这是一个很重要的事情.