论坛首页 Java企业应用论坛

论面向组合子程序设计方法 之 微步毂纹生

浏览 87448 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-08-10  
charon 写道
ajoo 写道
引用
你总不会认为有些功能分别在的时候有,但是整合起来就没有了巴

这话难说。组合子的强大就在于可以把单独的一些功能组合起来完成复杂功能。
而不用组合子也能做到这点可不是不值一提的小事。
需求中的那些if-else能不能实现,还真不是这些功能分别都支持就能证明用这些if-else整合起来之后仍然支持的。

如果是这样,那我相信同样的场景即便用上了组合子,仍然不能保证整合起来之后仍然能够支持。毕竟你这里提到的组合子也没有魔咒在,而且,如果用较为随意的方式来设计组合子,很可能本来对于组合系统而言的一些特性已经不成立了。

可是我已经演示了组合子怎样轻松地支持这些if-else的呀。而你只是告诉我这些功能单独地都可以用log4j做,于是就推导出来组合起来也必然能做?似乎缺了点论据吧?
0 请登录后投票
   发表时间:2005-08-10  
charon 写道
ajoo 写道
charon 写道
ajoo 写道
正交性是手段,不是目的。适当有些重叠不见得有什么大不了的。我前面回答swing的那个action的例子,map这个组合子本来可以用bind来推演,但是直接实现也无不可。做一件事有多种方法是很自然的,有什么必要避免?


这是一个坎,不允许重复,那么很容易把握。但是,稍微有一点重复,这个度就很难说了。不同的人会有不同的做法,最后导致从正交的观点出发,设计出一个缠绕的东西来。
perl自豪的地方是同一件事情可以有很多种方法,但是这也是被很多人所诟病的。

有一件事只有一种方法的语言么?比如说?


现实应用的语言,应该说没有,但是有些语言,比如python,有些接近这个目标了。
这里的关键是CO“声称”从正交出发,但是却混同了非正交的做法,hehe.,在说法上就需要变一变了。

我怀疑这个说法。说python接近一种事情只有一种解决方法,也不知道是夸它还是骂它呢。

另外,重申一下,我不认为一种事情有两种途径和“正交”有什么冲突。

所谓“正交”,是说,一个组合子做且只做一件事。至于我是用1+1得到的2还是3-1,我不认为对正交性,或者对数学的完美性有什么影响。
要不,你可以论证一下“数学的非正交性”先?
0 请登录后投票
   发表时间:2005-08-10  
charon 写道
引用

我不知道你怎么会有这种想法。如果真是要解决的东西增加,oo的复杂度只怕会上升得更快,至少对这个logging得例子我相信是这样。

OO的解法中,因为静态层次结构的存在,复杂度在一定程度上是被分治的。至少在现在我还没有从你的表述中看到类似的机制。
引用

我对你说得这个组合子对接很感兴趣。能不能具体点?对了,如果你看看haskell,所谓combinator最大的好处就是组合子和组合子之间的组合。在fp里面的combinator的一个大强项怎么到这里变成弱点了?

fp出现很多年了,现在也一直没有成为应用上的主流(可能连支流也还算不上),我想里面肯定有内在的原因的。我不否认fp在某些方面的强大,但是更像知道它的应用范围,或者说它的边界在哪里,哪些事情做不了。
简单组合子和规则组成的系统,解空间的实用意义不大。复杂的系统,会有预知之外的情况出现。这个很难表述,一个线索是元胞自动机;另一个线索是可能比较实际一点,比如,就拿造房子来说,组合子可能就是砖头木块胶合物之类的,但是怎么保障用这些小粒度组合子构造出来的房门框架,能够和另外一些组合子组合而成的门能够大小匹配,钮合顺当?因为OO可以定义静态中间结构,可以自顶向下,这些都不是问题。但对于CO而言,似乎只有试错一途?


fp的不成功,原因是多方面的。教育,门槛过高都是问题。

而且,就我的分析,fp,co主要提供了一个自底向上的方法论。而这个方法论并没有提供有效的方法在问题规模庞大的时候分解问题。我觉得这是一个相当严重的缺陷。

其它,比如haskell,执着于纯fp,lazy,造成调试的极大不方便,这种对普通程序员在实际开发中遇到的问题的蔑视,是它发展的一大障碍。


还有,oo每个类有单独的名字空间,而fp,至少haskell, ml都没有这个。命名虽然看似美观问题,但是对程序的影响至关重大。


至于你说得所谓“扭和”,对不起,我还是看不懂你的意思。
0 请登录后投票
   发表时间:2005-08-10  
ajoo, 偶的建议是先完善基于组合作出来的log例子,按照你演示的功能,偶所得到的印象是:CO可以做一些trivial的事情,但是真正的实际应用呢?

偶举实际中遇到的log需求,你看看有没有兴趣改进你的log项目。

1. 偶前面提到过的性能问题:
如果Logger interface上,没有isEnable(int level)这个方法的话,偶该如何避免类似:logger.print(DEBUG, "string contact performance " + i + " issue"),在循环中所带来的性能问题?log4j提供了isDebugEnabled,isInfoEnabled这些方法,那么在你的log里面,是需要为所有的实现添加这个方法的实现?有没有可能通过另外的PerformanceLogger的接口做一个新的组合子?

2. 缺少一个void print(int level, Throwable e)方法
有时候即便是一个exception,也想按照不同的log等级输出,比如finally block里面,偶有时候可能会用logger.print(DEBUG, fileCloseException). 那么在你的log里面,也是需要为所有的实现添加这个方法的实现?

3. 组合子的简化
按照你所说的组合子的设计要简单,那么这个方法是不应该出现在接口里的:
void println(int level, String msg);
你一开始没有设计这个方法,而是到了TimestampLogger的时候,发现了时间和内容要在同一行里面的需求,不得已加上了这个东西,偶认为这样的修改是错误的。如何格式化输出内容是Logger实现者本身的事情,不能因为这个需求,而往组合子的接口里面添加这个方法。而且实际上不需要添加这个方法也可以实现在同一行里面输出时间和exception:
  public void printException(Throwable e){
    logger.println(ERROR, new Date().toString() + ": " + new ThrowableStringWriter(e));
  } 


4. charon说的分开package输出的功能
log4j提供的这个功能是偶在实际应用中最常用,也是非常有用的,比如
log4j.category.com.mycompany.orm=DEBUG
log4j.category.com.mycompany.mvc=INFO

这样就可以调整不同package的输出等级,方便测试和修正bug


5. 格式化
log4j提供了这样的功能, 做如下的设置:
log4j.appender.fileout.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS}[%24F:%-3L:%-5p]%x %m%n

可以输出如下的日志:
01-28 14:07:56.340[   ApplicationSetup.java:141:INFO ] Doing database check as requested in config file
01-28 14:07:57.391[       DatabaseUtil.java:675:INFO ] Database Product Name is MySql


这个也是非常实用的功能。

偶相信需求4,5和组合子没有关系,但是如果你真正去实现的话,并不是一个trivial的工作,要实现log4j的基本功能,还需要做很多工作.......

btw,这个年头技术不值钱,缺的是创意,你有空去写yan vs pico, spring,log4ajoo vs log4j,ajoobuild vs ant,远不如用CO写别人没有想到过的东西来得震撼......
0 请登录后投票
   发表时间:2005-08-10  
引用
按照你演示的功能,偶所得到的印象是:CO可以做一些trivial的事情,但是真正的实际应用呢?

演示,顾名思义,就不是做一个完善的系统出来。你要是看演示这么看,那么只怕80%的东西你看了演示都会觉得只能做trivial事情,比如那个aop。

我这个logger是做着自己用的,所以,既然用不到这些功能,而暂时又没有再造一个和log4j竞争的logger的想法,所以还真找不到什么动力花精力完善它。

co在fp里面也不是才用了一两天,你真的觉得fp里面就没有真正实际的应用吗?


引用

1. 偶前面提到过的性能问题:
如果Logger interface上,没有isEnable(int level)这个方法的话,偶该如何避免类似:logger.print(DEBUG, "string contact performance " + i + " issue"),在循环中所带来的性能问题?log4j提供了isDebugEnabled,isInfoEnabled这些方法,那么在你的log里面,是需要为所有的实现添加这个方法的实现?有没有可能通过另外的PerformanceLogger的接口做一个新的组合子?

我觉得不可能通过一个单独的组合子完成。毕竟,这个isEnabled()函数,是要放在Logger接口里面的。
这其实触及到了java语言的call-by-value的底线。若非如此,你以为sun会吃饱了撑的搞一个语言支持的assert出来?

不过,我倒是觉得,真的有必要在每个logger级别来处理isEnabled吗?一个全局的isEnabled不成吗?
如果可以,倒是真可以用assert来简化。

另外,如果用print,而不是println,那么也不需要isEnabled了,就这样:
logger.print(DEBUG, "string contact performance ");;
logger.print(DEBUG, i);;
logger.println(" issue");;

或者,如果构造一个数组的开销可以忍受的话:
log(logger, DEBUG, new Object[]{"string contact performance ", i, " issue"});;

也都不必你那个单独的isEnabled函数麻烦。尤其现在有了变长参数,语法更简单了。
log(logger, DEBUG, "string contact performance ", i, " issue");;



引用
2. 缺少一个void print(int level, Throwable e)方法
有时候即便是一个exception,也想按照不同的log等级输出,比如finally block里面,偶有时候可能会用logger.print(DEBUG, fileCloseException). 那么在你的log里面,也是需要为所有的实现添加这个方法的实现?

这好办。把printException()函数加一个参数就是了。

引用
3. 组合子的简化
按照你所说的组合子的设计要简单,那么这个方法是不应该出现在接口里的:
void println(int level, String msg);
你一开始没有设计这个方法,而是到了TimestampLogger的时候,发现了时间和内容要在同一行里面的需求,不得已加上了这个东西,偶认为这样的修改是错误的。如何格式化输出内容是Logger实现者本身的事情,不能因为这个需求,而往组合子的接口里面添加这个方法。而且实际上不需要添加这个方法也可以实现在同一行里面输出时间和exception:
  public void printException(Throwable e){
    logger.println(ERROR, new Date().toString() + ": " + new ThrowableStringWriter(e));
  } 

你是说print吧?那么你确定具体应用不会想用print?不一定吧?比如,我前面提到的用print来代替isEnabled,你觉得看上去是不是比你写的那个用isEnabled的代码舒服些?

另外,你给的这个方法,不大行的。把Throwable变成Writer,逻辑上就不对了。本来是调用forward_logger.printException(e),现在变成了logger.println(),谁敢保证forward_logger内部对printException的处理和ThrowableStringWriter一致?我怎么知道forward_logger对这个exception是打印getMessage(),print stack trace还是print execution trace?

组合子是要简单,但是也要完备。




引用
4. charon说的分开package输出的功能
log4j提供的这个功能是偶在实际应用中最常用,也是非常有用的,比如
log4j.category.com.mycompany.orm=DEBUG
log4j.category.com.mycompany.mvc=INFO

这样就可以调整不同package的输出等级,方便测试和修正bug

你说的没错。这个功能和logger无关。用yan container,可以方便地做到。不过是一个整合罢了。(当然,要求你的组件都是用ioc风格设计的。有没有兴趣看看用yan怎么做到?)
其实,这是一个个人看问题的角度问题。你关注的是找一个好用的工具,管他内部设计怎么垃圾。所以,外部的精装修,和其它系统的集成,方便的配置都非常重要。
而我关注的是介绍一种程序设计方法,可以非常优雅地设计程序。所以,这些整合的东西,至少不是我这个文章所关注的。


引用
5. 格式化
log4j提供了这样的功能, 做如下的设置:
log4j.appender.fileout.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS}[%24F:%-3L:%-5p]%x %m%n

可以输出如下的日志:
01-28 14:07:56.340[   ApplicationSetup.java:141:INFO ] Doing database check as requested in config file
01-28 14:07:57.391[       DatabaseUtil.java:675:INFO ] Database Product Name is MySql

这个和logger其实有那么点关系,就额外做个format的组合子就好了。这个我的build tool用不到,其实迄今为止我也没发现我什么地方真的需要这种格式化。



引用

btw,这个年头技术不值钱,缺的是创意,你有空去写yan vs pico, spring,log4ajoo vs log4j,ajoobuild vs ant,远不如用CO写别人没有想到过的东西来得震撼......

我从前是总想一鸣惊人的。后来发现自己真的不是天才,就放下了这个梦想。还是踏踏实实地一步一个脚印更有把握些。震撼不震撼,拿不出实在东西都是扯淡。
0 请登录后投票
   发表时间:2005-08-10  
ajoo 写道
charon 写道
ajoo 写道
引用
你总不会认为有些功能分别在的时候有,但是整合起来就没有了巴

这话难说。组合子的强大就在于可以把单独的一些功能组合起来完成复杂功能。
而不用组合子也能做到这点可不是不值一提的小事。
需求中的那些if-else能不能实现,还真不是这些功能分别都支持就能证明用这些if-else整合起来之后仍然支持的。

如果是这样,那我相信同样的场景即便用上了组合子,仍然不能保证整合起来之后仍然能够支持。毕竟你这里提到的组合子也没有魔咒在,而且,如果用较为随意的方式来设计组合子,很可能本来对于组合系统而言的一些特性已经不成立了。

可是我已经演示了组合子怎样轻松地支持这些if-else的呀。而你只是告诉我这些功能单独地都可以用log4j做,于是就推导出来组合起来也必然能做?似乎缺了点论据吧?

faint, 一点幽默感没有,难道真没看到我的那句原话是反问的意思?
引用
你总不会认为有些功能分别在的时候有,但是整合起来就没有了巴

如果平铺直叙一点的说,就是这些功能整合起来也可以做到。这个本来就是log4j的功能,不是我说它有就有,我说它没有就没有,文档、源码都在那儿摆着呢。
至于你说的if/else整不起来的情况,必须先举个这样的例子,比如用OO的办法整不起来,用CO的办法就能够整起来,那样就了结了
0 请登录后投票
   发表时间:2005-08-10  
ajoo 写道
charon 写道
ajoo 写道
charon 写道
ajoo 写道
正交性是手段,不是目的。适当有些重叠不见得有什么大不了的。我前面回答swing的那个action的例子,map这个组合子本来可以用bind来推演,但是直接实现也无不可。做一件事有多种方法是很自然的,有什么必要避免?


这是一个坎,不允许重复,那么很容易把握。但是,稍微有一点重复,这个度就很难说了。不同的人会有不同的做法,最后导致从正交的观点出发,设计出一个缠绕的东西来。
perl自豪的地方是同一件事情可以有很多种方法,但是这也是被很多人所诟病的。

有一件事只有一种方法的语言么?比如说?


现实应用的语言,应该说没有,但是有些语言,比如python,有些接近这个目标了。
这里的关键是CO“声称”从正交出发,但是却混同了非正交的做法,hehe.,在说法上就需要变一变了。

我怀疑这个说法。说python接近一种事情只有一种解决方法,也不知道是夸它还是骂它呢。

另外,重申一下,我不认为一种事情有两种途径和“正交”有什么冲突。

所谓“正交”,是说,一个组合子做且只做一件事。至于我是用1+1得到的2还是3-1,我不认为对正交性,或者对数学的完美性有什么影响。
要不,你可以论证一下“数学的非正交性”先?

hehe,看来大家需要先就正交这个概念达成一致。
首先,正交系统有一个核心,比如对于命题逻辑系统,与或非三者只有两个是必须的,所以只有两个才能够进入这个核心。假设是 "与"/"非",这两个是原子运算。
其次,核心上面有很多便利工具,比如"或"可以用"与"/'非"的组合表示,为了便利,也把它当作一个直接运算符,实际上只是一个助记符号。还有很多别的,比如"异或"之类的。这些都可以分解为原子的组合
关键的一点,这个系统里面的所有事情都是与非两个运算搞定的,其他的东西,都是他们的某种组合。此时,这样构造的系统可以称为是正交的。
前面所说的一种事情有两种途径,指的并不是一个推理既可以用"与"/"非",又可以用"与"/"或",因为这两种途径最终都可还原为与非,所以并不影响正交性。而是指如果有人把'或"也引入核心,那么,这样两个途径就是本质不同的了,因为到了原子,是不能再分解下去了。这时,这个系统就不是正交系统。
至于"数学系统"的正交还是不正交性,则是根据你怎样构建这个系统决定的。有了原子数字,有一些运算规则,如果恰巧把某些不必要的东西当作原子运算,比如加减乘除都是原子运算(而且恰巧这些运算的含义都符合传统习惯),那么这个系统显然不是正交的。还有一个比如,就是用两个维度可以搞定的平面推演系统,偏偏要用三个维度来弄,那就不是正交了。
在上面的基础上,可以那么说,如果你构建的CO系统中有A,B,C三个组合子(当然是原子了),对于某个东西,A/B的某种组合和B/C的某种组合都能够解决,那么,显然,你这个系统就不是正交的。
所以,认为一个组合子只作一件事情就是正交性是不确切的,还必须确保原子组合子的线性无关。正交并不是一个容易达到的目标。
0 请登录后投票
   发表时间:2005-08-10  
charon 写道
ajoo 写道
charon 写道
ajoo 写道
charon 写道
ajoo 写道
正交性是手段,不是目的。适当有些重叠不见得有什么大不了的。我前面回答swing的那个action的例子,map这个组合子本来可以用bind来推演,但是直接实现也无不可。做一件事有多种方法是很自然的,有什么必要避免?


这是一个坎,不允许重复,那么很容易把握。但是,稍微有一点重复,这个度就很难说了。不同的人会有不同的做法,最后导致从正交的观点出发,设计出一个缠绕的东西来。
perl自豪的地方是同一件事情可以有很多种方法,但是这也是被很多人所诟病的。

有一件事只有一种方法的语言么?比如说?


现实应用的语言,应该说没有,但是有些语言,比如python,有些接近这个目标了。
这里的关键是CO“声称”从正交出发,但是却混同了非正交的做法,hehe.,在说法上就需要变一变了。

我怀疑这个说法。说python接近一种事情只有一种解决方法,也不知道是夸它还是骂它呢。

另外,重申一下,我不认为一种事情有两种途径和“正交”有什么冲突。

所谓“正交”,是说,一个组合子做且只做一件事。至于我是用1+1得到的2还是3-1,我不认为对正交性,或者对数学的完美性有什么影响。
要不,你可以论证一下“数学的非正交性”先?

hehe,看来大家需要先就正交这个概念达成一致。
首先,正交系统有一个核心,比如对于命题逻辑系统,与或非三者只有两个是必须的,所以只有两个才能够进入这个核心。假设是 "与"/"非",这两个是原子运算。
其次,核心上面有很多便利工具,比如"或"可以用"与"/'非"的组合表示,为了便利,也把它当作一个直接运算符,实际上只是一个助记符号。还有很多别的,比如"异或"之类的。这些都可以分解为原子的组合
关键的一点,这个系统里面的所有事情都是与非两个运算搞定的,其他的东西,都是他们的某种组合。此时,这样构造的系统可以称为是正交的。
前面所说的一种事情有两种途径,指的并不是一个推理既可以用"与"/"非",又可以用"与"/"或",因为这两种途径最终都可还原为与非,所以并不影响正交性。而是指如果有人把'或"也引入核心,那么,这样两个途径就是本质不同的了,因为到了原子,是不能再分解下去了。这时,这个系统就不是正交系统。
至于"数学系统"的正交还是不正交性,则是根据你怎样构建这个系统决定的。有了原子数字,有一些运算规则,如果恰巧把某些不必要的东西当作原子运算,比如加减乘除都是原子运算(而且恰巧这些运算的含义都符合传统习惯),那么这个系统显然不是正交的。还有一个比如,就是用两个维度可以搞定的平面推演系统,偏偏要用三个维度来弄,那就不是正交了。
在上面的基础上,可以那么说,如果你构建的CO系统中有A,B,C三个组合子(当然是原子了),对于某个东西,A/B的某种组合和B/C的某种组合都能够解决,那么,显然,你这个系统就不是正交的。
所以,认为一个组合子只作一件事情就是正交性是不确切的,还必须确保原子组合子的线性无关。正交并不是一个容易达到的目标。

咳。合着你说的只是在原子级别不能有两个原子干同样的事情?这有什么难的?那么多语言,只怕功能在基础设施上重叠的也不多吧?即使有重叠,理论上也可以看作为了方便提供的一个shortcut,没什么大不了的。
而在此基础上的非原子级别的组合上如果一件事可以有两个方法是无所谓的了?那不就没问题了?
0 请登录后投票
   发表时间:2005-08-10  
引用
如果平铺直叙一点的说,就是这些功能整合起来也可以做到。这个本来就是log4j的功能,不是我说它有就有,我说它没有就没有,文档、源码都在那儿摆着呢。
至于你说的if/else整不起来的情况,必须先举个这样的例子,比如用OO的办法整不起来,用CO的办法就能够整起来,那样就了结了

你就直接说:就是有,就是有,反正文档都在那呢,自己看去。


不就结了?


这个举证责任的问题,就是个皮球,我举证了co可以做,您老说,oo也可以作,不信你举证。噌!皮球就又到我脚底下了。

得了,我怕了。有时间我干点更有意义的不好吗?我就当它有好了。这种用oo方法作出来的东西,要说任何功能,只要实现者想到了,肯花时间,花复杂度做,总归会有的,只不过实现上不象co这么是通过不影响总体复杂度的自然推演罢了。也不会象co这样有对没有想到的需求的一定的适应能力。

我原来怀疑的,是你对我那些需求是不是仔细看了。因为从你的几个回答来看,总是觉得答非所问,让我不得不怀疑你只是想当然地认为有。

不过算了。log4j有没有某个功能对我也不重要。我又不是要做一个跟它竞争的logger,一个演示而已,何必较真?我就当它有好了。
0 请登录后投票
   发表时间:2005-08-10  
ajoo 写道
引用
如果平铺直叙一点的说,就是这些功能整合起来也可以做到。这个本来就是log4j的功能,不是我说它有就有,我说它没有就没有,文档、源码都在那儿摆着呢。
至于你说的if/else整不起来的情况,必须先举个这样的例子,比如用OO的办法整不起来,用CO的办法就能够整起来,那样就了结了

你就直接说:就是有,就是有,反正文档都在那呢,自己看去。


不就结了?


这个举证责任的问题,就是个皮球,我举证了co可以做,您老说,oo也可以作,不信你举证。噌!皮球就又到我脚底下了。

得了,我怕了。有时间我干点更有意义的不好吗?我就当它有好了。这种用oo方法作出来的东西,要说任何功能,只要实现者想到了,肯花时间,花复杂度做,总归会有的,只不过实现上不象co这么是通过不影响总体复杂度的自然推演罢了。也不会象co这样有对没有想到的需求的一定的适应能力。

我原来怀疑的,是你对我那些需求是不是仔细看了。因为从你的几个回答来看,总是觉得答非所问,让我不得不怀疑你只是想当然地认为有。

不过算了。log4j有没有某个功能对我也不重要。我又不是要做一个跟它竞争的logger,一个演示而已,何必较真?我就当它有好了。

(偶准备唐僧了...,嘿嘿,最近比较喜欢说高话. 高来高去好的, 都闹虚的.  )
嗯,所以说啦,在论坛讨论技术程度比较高的问题时,往往很难争论出结果来.
细节性的讨论太容易陷入无休止的嘴舌之中,对于这种情况,我还是觉得作者给出系统的理论总结和一些稍为详细的注解例子, 觉得可取得细细分析和自己实践,觉得不合理的就当走马观花罢了,要是真的你来我往讨论的话,还真讨论不出什么结果来.
而且,现在大家讨论问题似乎都有一种默认的习惯:  例子总归是最好的解析办法.
诚然,例子确实帮助理解,但是在比较复杂和技术的讨论中,例子往往是妨碍讨论的东西,因为你不知道你举的例子是否具有足够的力度来解析你的思路,别人可能觉得太简单了,然后他给你提出他所碰到的问题领域的东西,可能你没有接触过或者没有足够的时间考虑,给出的解答比较苍白无力,即便能够解答,但是你的解答的思路没有符合提问者脑子中即成的"审美观" ,他又有意见了,向你提,你又得思考这个意见,然后又回答,回答比较满意了,可是还是达不到他所真正需要的效果..............................(无限循环中)

所以,嘿嘿,我提倡大家都要说大道理,少谈具体,多说虚的. 让别人看得似乎很有玄妙,然后需要细细分析,然后才能比较明白,不明白他就很怕怕的向你咨询,然后你告诉它你真正的意思,因为对方仔细思考了一遍或者两边或者三遍了,所以他一听就明白就真正表达的意思,然后他又仔细整理自己的思路,用玄乎其玄的三言两语的大道理跟你提问 ,你看了,哦,似乎比较深奥哦,然后仔细推敲,不甚明了的,向他索求其要表达的意图 ,然后他回答你的提问 ,针对他的提问,你整理一下思路再次用更玄乎的道理跟他讲,他仔仔细细看了,我靠,更加深奥,再仔细分析, 终于恍然大悟,然后再思考虑一下,似乎逐渐明白作者真正的设计思路,觉得这个设计思路还是比较可以偷学东西,偷偷学了一下,发现又有很多不适很实用的地方,跟你又说了一番大道理,顺便吹嘘了他对你项目的评价,如此尔尔...........(唉,脑力劳动好累啊。)
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics