锁定老帖子 主题:论面向组合子程序设计方法 之 微步毂纹生
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-08-09
ajoo 写道 一个人说明白,比如你或者T1,倒还好说,毕竟你们本身对这个概念就有一定了解。
但是这么多人说理解,赞同,我就有点怀疑了。不大可能是我的表达能力超强(其实,对这个,我有自知之明的,以前多少次悲惨遭遇都是和我表达不清有关系),也许更可能的是,我的地瓜被当作土豆卖了。 说这话其实有点不知好歹,伤人一大片之嫌,先道个歉先。我是希望,说理解的同学们,好意我表示感谢,但是请还是仔细看看,别闹出我当年“歌德巴赫猜想?简单,就是一个加一个等于一对嘛”的错误来。 庄子曰:条鱼出游从容,是鱼之乐也,惠子曰:子非鱼,安知鱼之乐?庄子曰:子非我,安知我不知鱼之乐? 嘿嘿 从某种角度来讲,人是永远无法真正理解别人的想法的 |
|
返回顶楼 | |
发表时间:2005-08-09
我有几个问题想请教ajoo,combinator的来源是哪里?究竟如何判断combinator够不够用?combinator如何才能做到最基本?combinator是不是还会在某些情况下被再次的分解为combinator的combinator?
至于说oo是基于归纳的,co是基于演绎的,我想证据还不够充足。而且oo也是可以演绎的,这个ajoo也不应该否认。而combinator是不是就不需要归纳,就可以自然的产生呢? 同时我还需要知道fo,是不是自顶向下的,而且是不是应该字顶向下的? 哈哈,这样好,还是 这样好?或者说什么时候应该 ,什么时候应该 ? |
|
返回顶楼 | |
发表时间:2005-08-09
第四节:新约
http://forum.iteye.com/bloglist.php?userid=6423 |
|
返回顶楼 | |
发表时间:2005-08-09
引用 co是银弹吗?当然不是,至少以我的功力没有这种自信。 遇到复杂的问题我也是先分解需求,面向接口的。只有问题的规模被控制在了一定的范围,我才会试图用co来解决问题。靠着对co的一些经验和感觉,一旦发现了可以组合子化的概念,成果会非常显著。 那么就是自顶向下分解需求,自底向上构建系统了? 至少在这一点上,和被革命的对象还是有那么一点点相似。 |
|
返回顶楼 | |
发表时间:2005-08-09
ozzzzzz 写道 combinator的来源是哪里?
什么意思?就是一个我们发现可以组合子化的概念。最简单的如predicate,ant的FileSelector。 ozzzzzz 写道 究竟如何判断combinator够不够用? 基本的0,1往往是要有的。 如果这个概念不返回值,那么0就是什么也不做。1是做一件最最简单的事。 如果它返回值,那么0应该是抛某个与定义的exception,1是返回某个值。 然后,往往有顺序/分支。这些几乎是任何组合子都共享的特性。 再然后,如果要处理异常逻辑,那么try-catch-finally。 比如说try_catch(logger1, SomeException.class, logger2)就是说,如果logger1抛SomeException,那么就调用logger2。 对真正复杂的组合子,往往要遵循一个monad规则,其中有return/bind两个概念。我后文会提到一点。好在这个例子里面用不到。 剩下的,就基本上看你的需求的功能了。如果某个功能被认为是一个原子功能,那么实现一下,否则就组合。 ozzzzzz 写道 combinator如何才能做到最基本?
尽量作到呗。不行就重构。如果你发现你的combinator还可以继续分解,那么就分解它。 ozzzzzz 写道 combinator是不是还会在某些情况下被再次的分解为combinator的combinator?
一个大的combinator可以由若干个小的combinator组成。 ozzzzzz 写道 至于说oo是基于归纳的,co是基于演绎的,我想证据还不够充足。而且oo也是可以演绎的,这个ajoo也不应该否认。而combinator是不是就不需要归纳,就可以自然的产生呢? 这不是证明。只是从我对"OO"的定义中导出的结论。我说过了,我的定义不见得权威,肯定有不同的定义。只不过我文章里面提的“oo”就是这种归纳方法论。 至于说是否归纳和演绎不能混合。当然可以,oo也可以和fo, po混合,怎么方便怎么来被。 ozzzzzz 写道 同时我还需要知道fo,是不是自顶向下的,而且是不是应该字顶向下的? 哈哈,这样好,还是 这样好?或者说什么时候应该 ,什么时候应该 ? 我认为的fo,(函数式),就是自底向上为主的思想。这是我个人的理解。没有权威性。 至于什么时候top-down,什么时候bottom-up,我文章里面提了一下。 |
|
返回顶楼 | |
发表时间:2005-08-09
charon 写道 引用 co是银弹吗?当然不是,至少以我的功力没有这种自信。 遇到复杂的问题我也是先分解需求,面向接口的。只有问题的规模被控制在了一定的范围,我才会试图用co来解决问题。靠着对co的一些经验和感觉,一旦发现了可以组合子化的概念,成果会非常显著。 那么就是自顶向下分解需求,自底向上构建系统了? 至少在这一点上,和被革命的对象还是有那么一点点相似。 也许可以说, oo在问题规模不大,概念比较单一,但是灵活性要求高的场合(或者说,就剩一块石头了,但是这块石头又大又硬)并不是一个趁手的工具。 比如说,我的yan container,概念很简单,就是创建组装组件。但是同时,对组建的组装要求很高的灵活性,这时就是一个完美的co的场合。 |
|
返回顶楼 | |
发表时间:2005-08-09
仅从这个logging的例子,我还没有看到CO的威力(不过,我倒是相信CO有着巨大威力)。在我的概念里面,一个东西(A)要补充或者强于另一个东西(B),则要么A能够做到B做不到的事情,要么A能够轻松的做一些B做起来很繁复的事情。
这里的例子,相比log4j并没有特别的地方。log4j把log级别和输出地解耦开来,实际上也是一种正交(这是对使用者而言,而不是开发者,但是我等都是使用者)。而这里则又引入了具体的exception(机制很粗陋,把exception名字直接编码到logger名字中,看起来并没有实现针对exception空间的完整处理机制),不过实际上相当于是对log级别的细化,或者说log级别和exception在概念上并不是正交的(一个级别可以对应于多类exception,但是一类exception则通常只能对应于一个级别),这是一个瑕疵。当然,这只是基于正交的设计的一个基础方面,可能作者更关注高阶特性。 另一个问题是这个logger接口带来的,使用PrintWriter/OutputStream固然好整,但是一个直接的结果是,在多线程/多进程环境下咋办?一个logger长时间的捏着一个文件/socket或者别的什么东西的handler,形象不太好。 |
|
返回顶楼 | |
发表时间:2005-08-09
ajoo 写道 charon 写道 引用 co是银弹吗?当然不是,至少以我的功力没有这种自信。 遇到复杂的问题我也是先分解需求,面向接口的。只有问题的规模被控制在了一定的范围,我才会试图用co来解决问题。靠着对co的一些经验和感觉,一旦发现了可以组合子化的概念,成果会非常显著。 那么就是自顶向下分解需求,自底向上构建系统了? 至少在这一点上,和被革命的对象还是有那么一点点相似。 也许可以说, oo在问题规模不大,概念比较单一,但是灵活性要求高的场合(或者说,就剩一块石头了,但是这块石头又大又硬)并不是一个趁手的工具。 比如说,我的yan container,概念很简单,就是创建组装组件。但是同时,对组建的组装要求很高的灵活性,这时就是一个完美的co的场合。 这样的场景,好像某些杂合的动态语言,比如python/ruby之类的,还有那个新来的groovy(很多东西直接套java,不如python来的自然) ,用起来更加顺手一点吧。在单独的这种场景中,我基本不会去考虑看起来是不是那么OO。但是,如果需要集成到大的环境中,可能就需要一些思量了。 |
|
返回顶楼 | |
发表时间:2005-08-09
引用 也许你还无法理解。平时我们在java中用那么几个decorator,本身非常简单,所以debug, trace都不是问题。可是,一旦oriented起来,情况就不同了。街上有两辆车和成千上万辆车,对交通造成的压力截然不同。 什么叫“oriented起来”? 我看来看去logger的例子还是觉得是decorator,你上面的话也似乎在说明就是decorator,只是你把decorator发挥到极致乐。 组合子并不像你所说的那么神奇,不是说你什么需求都能演绎,实际上, 根据需求,你需要各种组合子,根据变化的需求,你仍然需要更多的组合子, 比如,现在有个需求,当logger级别超过一个值的时候必须写到Logger文件中,否则只需要输出到控制台即可;或者是某个级别的log需要单独输出到一个独立的log文件中; 现在你现有的是不够的,必须增加,但是这些需求是你一开始不能料到的 感觉像拿起乐decorator这个锤子来找钉子。 如果是一个简单的单表增删改,我不知道你怎么用decorator这个锤子敲,恐怕还是要回归平凡。 |
|
返回顶楼 | |
发表时间:2005-08-09
charon 写道 仅从这个logging的例子,我还没有看到CO的威力(不过,我倒是相信CO有着巨大威力)。在我的概念里面,一个东西(A)要补充或者强于另一个东西(B),则要么A能够做到B做不到的事情,要么A能够轻松的做一些B做起来很繁复的事情。
不知道你觉得用几个简单到家的组合子组合出来那些繁复的需求是不是算“轻松”呢? charon 写道 这里的例子,相比log4j并没有特别的地方。log4j把log级别和输出地解耦开来,实际上也是一种正交(这是对使用者而言,而不是开发者,但是我等都是使用者)。 你可以示范一下怎么用log4j实现我这些需求。倒是一个很好的比较呢。 charon 写道 而这里则又引入了具体的exception(机制很粗陋,把exception名字直接编码到logger名字中,看起来并没有实现针对exception空间的完整处理机制),不过实际上相当于是对log级别的细化,或者说log级别和exception在概念上并不是正交的(一个级别可以对应于多类exception,但是一类exception则通常只能对应于一个级别),这是一个瑕疵。当然,这只是基于正交的设计的一个基础方面,可能作者更关注高阶特性。 我并不想把系统搞得太复杂。现在这个已经够用了。如果有更加变态的需求,也是可以重构的。 不过printException是必要的。仅仅log(String)就失去了对exception特殊处理的能力。 你有什么更好的设计思路吗?不妨提出来看看。 charon 写道 另一个问题是这个logger接口带来的,使用PrintWriter/OutputStream固然好整,但是一个直接的结果是,在多线程/多进程环境下咋办?一个logger长时间的捏着一个文件/socket或者别的什么东西的handler,形象不太好。 好办啊。再做一个combinator,在每次log的时候打开关闭一下文件。要不要我show一下? |
|
返回顶楼 | |