该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-09-17
ajoo 写道 稍微看了一下rails的tutorial(否则robbin的话都看不懂)
针对robbin的说法有几个问题: 1。为什么说active record不OO?具体指什么? 2。关于纵向分解。什么妨碍了纵向分解?view和controller就是可以分开的吧?如果存在active record不缺省支持的复杂的business logic,难道不可以单独独立出来么?ioc注射我是没有看见怎么解决,因为似乎model对象的创建都是framework自己封闭搞定的。但是service locator没问题呀。或者聪明些,弄一个统一的类似"dependency :service1, :service2, :service3"的这种东西来,和一个外部ioc容器连接起来都没有问题。 3。关于横向分解。ruby应该是有mixin的吧?那么,不同的人分管一个controller的不同action,写成module,最后mixin进来不成么? 1、rails的ActiveReord是把持久化操作和domain logic都放在model里面,而一般来说持久化操作往往要分离出去。 2、我说的纵向分解的意思是说,用rails开发,你让一个人写Controller,另外一个人写Model,第三个人写View,这三个人的开发效率都会降低到可怜的程度,因为这三层之间互相之间的隐式约定太多了。但是在Java开发中,你让一个人负责持久层,一个人负责业务层,一个人负责web层,通常合作起来还是高效的。 3、按照你那样做似乎也是可以的,但是我直觉上感觉这样做会把整个项目代码搞的很复杂的。 |
|
返回顶楼 | |
发表时间:2006-09-17
buaawhl 写道 说active record 不够OO,可能主要是说rails plugin给 active record 里面 mixin 更多的method。造成一个Object 的方法非常多,接口非常宽。 OO极端思想,一个类只做一件事情。从这个观点来看,确实不够OO。 mixin不是什么好东西。没办法的时候才用的。一般只应该用在框架中,正如cglib这些东西只能用在框架中,正经的项目开发中怎么能使用呢? 一般的小网站项目中可能没有那么多的service,都是curd,query和functional代码。service locator的帮助有限。 我怎么觉得这是oo牛角尖思想? active record负责一个model的persistence,为什么不是一件事? 接口宽窄,要看要描述的东西,如果就有那么多方法,宽些又怎么? 更何况,这些东西又不是硬写进去,而是通过mixin, meta-programming进去的,根据java这种什么都得自己硬写的语言的一些法则就不见的适用。 一般一个模块的设计要从两个方面考虑: 1。从最终用户的角度,一个active record的接口只要自然好用就好,谁关心内部怎么写的? 2。从实现角度,只要不是把所有的代码都堆在一个类里面,通过delegate, meta-program, mixin而产生的东西并不会因为类的方法过多造成问题。 mxin,我是觉得不错的冬冬。不至于是没办法才用。(觉得比继承还要好呢) |
|
返回顶楼 | |
发表时间:2006-09-17
robbin 写道 ajoo 写道 稍微看了一下rails的tutorial(否则robbin的话都看不懂)
针对robbin的说法有几个问题: 1。为什么说active record不OO?具体指什么? 2。关于纵向分解。什么妨碍了纵向分解?view和controller就是可以分开的吧?如果存在active record不缺省支持的复杂的business logic,难道不可以单独独立出来么?ioc注射我是没有看见怎么解决,因为似乎model对象的创建都是framework自己封闭搞定的。但是service locator没问题呀。或者聪明些,弄一个统一的类似"dependency :service1, :service2, :service3"的这种东西来,和一个外部ioc容器连接起来都没有问题。 3。关于横向分解。ruby应该是有mixin的吧?那么,不同的人分管一个controller的不同action,写成module,最后mixin进来不成么? 1、rails的ActiveReord是把持久化操作和domain logic都放在model里面,而一般来说持久化操作往往要分离出去。 2、我说的纵向分解的意思是说,用rails开发,你让一个人写Controller,另外一个人写Model,第三个人写View,这三个人的开发效率都会降低到可怜的程度,因为这三层之间互相之间的隐式约定太多了。但是在Java开发中,你让一个人负责持久层,一个人负责业务层,一个人负责web层,通常合作起来还是高效的。 3、按照你那样做似乎也是可以的,但是我直觉上感觉这样做会把整个项目代码搞的很复杂的。 1。我没有看ActiveRecord的实现代码。也许它的实现确实不oo,但是从使用者的角度我倒看不出来哪里不OO,无非就是一些个库函数。有什么oo不oo的? 2。嗯。如果model, controller都比较简单的话,却是分开的代价要大于收益。不过此时也本来就没必要分开吧?我说的是如果有一些比较复杂的商业逻辑,比如搞个规则引擎什么的,纵向分解应该没什么不可能吧? 3。恩。没实践过也不好说。我的感觉倒是没觉得这会造成复杂性。反正是一个想法,robbin可以考虑有没有可能性。 |
|
返回顶楼 | |
发表时间:2006-09-17
model和持久化绑定却是有点问题。
不过,问题主要还是在view直接用po把? controller是直接也好,绕八道弯也好,总归要调用po的。 而rails里面view用po可能并不象java里面那么严重。 rails是动态类型的。view自己并没有强制要求用po,使用者(或者rails框架)要是高兴,完全可以把po复制成vo再传递给view。反正view层只要你给它提供了那些field就行了。 这就像面相接口编程,view只要这个IForum接口,至于你controller是把PersistenceForum直接给传过来,或者通过一个adapter传过来,或者弄个vo,先把po拷贝到vo再传过来,view层都无所谓。 rails只是缺省没有做这个po->vo的copy过程。我觉得只要没有直接耦合,不做这个copy一般来说挺好的。 |
|
返回顶楼 | |
发表时间:2006-09-17
ajoo 写道 buaawhl 写道 说active record 不够OO,可能主要是说rails plugin给 active record 里面 mixin 更多的method。造成一个Object 的方法非常多,接口非常宽。 OO极端思想,一个类只做一件事情。从这个观点来看,确实不够OO。 mixin不是什么好东西。没办法的时候才用的。一般只应该用在框架中,正如cglib这些东西只能用在框架中,正经的项目开发中怎么能使用呢? 一般的小网站项目中可能没有那么多的service,都是curd,query和functional代码。service locator的帮助有限。 我怎么觉得这是oo牛角尖思想? active record负责一个model的persistence,为什么不是一件事? 接口宽窄,要看要描述的东西,如果就有那么多方法,宽些又怎么? 更何况,这些东西又不是硬写进去,而是通过mixin, meta-programming进去的,根据java这种什么都得自己硬写的语言的一些法则就不见的适用。 一般一个模块的设计要从两个方面考虑: 1。从最终用户的角度,一个active record的接口只要自然好用就好,谁关心内部怎么写的? 2。从实现角度,只要不是把所有的代码都堆在一个类里面,通过delegate, meta-program, mixin而产生的东西并不会因为类的方法过多造成问题。 mxin,我是觉得不错的冬冬。不至于是没办法采用。(觉得比继承还要好呢) 我说的是,rails plugin。不是active record本身。active record本身,我不是说了吗,非常OO。 rails plugin是给这一个Object增加各种act as的功能。这就涉及到mixin好还是坏了。 先不管module的重用作用。如果用module mixin把一个类的功能代码分开,就相当于把一个类,拆成几个文件来写,作用类似于partial class。如果不是非常必要,这有什么好处呢?同一个scope,要考虑命名冲突,做一个module,还要想着其他module,各种麻烦。 mixin和delegate是相对的。mixin是横向,delegate是纵向的。mixin是同一个class scope,delegate是多个class scope。而且只有delegate才能更好的使用IoC。 module mixin当然有用处,我们都知道有些情况下,多重继承的好处,不用delegate很多methond。但应该限制使用,不应该成为主要开发方法。 robbin给的学习笔记不错。比我找到的那个目录强多了。虽然主要是管理和市场方面。 关于robbin的“缺乏知音”的悲叹。我对rails有些偏见,这个我承认。 我主要的观点是认为,robbin对ruby语法的批评,有点把rails的问题怪在ruby头上的意思。Ruby语法并没有大的毛病,可以胜任企业开发。RoR当然不胜任,这个不用说了,DHH自己都说了。 |
|
返回顶楼 | |
发表时间:2006-09-17
对Rails开发方式我也在思考,对动态类型和meta programming已有的一些实践需要调整,也许需要引入一些新的做法。不得不说目前的大部分Rails项目都是少数几个人搞出来,即使那些访问量较大的成功站点不代表其代码量就大到需要很多人编程。所以对大规模的项目如何管理开发没有什么典型的例子。Getting Real涉及一些,不过更多是讲商业上的而不是软工上的实践。
动态语言不使用强制的interface而是用duck type,也就是隐性的接口。这种对象界面间的隐性接口在Rails里被进一步扩大,也就是robbin说的mvc之间的各种约定。显然在这种情况下测试被放在一个更重要的地位上,但是麻烦在于有些约定是不是那么容易测试的(何况Robbin赶时间没写测试。。。)。没有测试就不敢动别人的代码,不小心破坏了某些约定也无知无觉。但是我感觉即使Rails内置了多达三个层次上的测试手段(基本对应MVC三层),面对那些鬼斧神工般的class_eval和monkey patch还是有些力不从心,需要更智能的覆盖测试工具。我一直很喜欢Matz说过的Ruby设计哲学:A sharp knife may cut your fingers, but it's better than a dull one. 想少受伤怎么办呢?长远的办法是磨练使用技术,而直接的就是加强防护带手套咯。至于那些说Ruby过于灵活的就好比说要把刀磨钝点才更安全一样 如何磨练技术和加强防护这是值得长期研究的。 Robbin说的纵向分割困难我也有体会,比如validation和权限系统几乎要贯穿mvc三层,有些情况下MVC要清晰切分确实不如理论上那么容易。从实践角度讲无需追求那种纯洁性,但是软工角度上确实不容易分工。至于横向分割还好吧,对复杂的逻辑我也见过用命名域分割的,虽然这种做法会需要调整route和一些helper,甚至一些plugin。至于一个controller的action太多我认为是设计问题,scaffold给人的一个不好的错觉是误以为一个controller得对应一个model。其实一个controller对应的是一个function,它可以对应一个model或几个model, 一个model也可以被几个controller对应。如果一个controller太臃肿,function可以重新划分一下。 最后Java界积累的那些模式和工具(AOP, IoC之类)哪些能套用哪些不能或哪些需要修改才能适用到Rails上不是简单能分析出来的,估计需要比较长的时间才能融合。这个过程可能非常慢,因为大部分用Rails的人主要关心get job done并且符合自然和美感,大家喜欢谈论是那些美妙的hack而不是书本上的UML。C++/Java的设计模式其实很早在Python和Ruby社团都有人研究,但是始终很少有人刻意强调。Why? 我们不要忘记设计模式是怎么出来的,是人们经过长年累月的使用OO语言(主要是C++)总结出来的那些反复出现的好的设计思路。所以对那些非C++类的语言,一是需要时间积累,二是出现的新模式可能和现在的不同, 三是需要足够大的项目才会促使人思考这些问题,否则就不值得花这个力气。 |
|
返回顶楼 | |
发表时间:2006-09-17
buaawhl 写道 Ruby的阻碍在于什么呢? 我的个人看法,成也萧何,败也萧何。成也Rails,败也Rails。 “专注于解决简单的问题,将其他复杂、头痛、难解的留给对手” 看看这个口号。谁也不是傻瓜。谁不知道做简单赚大钱的事情。 Signal37成功了,但是这种模式是无法简单复制的。大家都争着去做简单的事情得了。 确实,人类还有相当多的随便实现一下就可以满足的简单需求可以挖掘,但是肯定远远少于Web2.0公司的数目。 你想证明Ruby的阻碍在于Rails,因为现在Rails的策略专注于web2.0泡沫?呵呵,但是即使没有Rails,90%简单的web需求还是存在的,web2.0照样有人搞。现在有工具能提高效率,何乐而不用?新的需求不断被市场发现,然后被大量公司通过竞争抓住机会,这过程中必然有公司被淘汰。你怎么推理出这会阻碍某种技术呢?以前网络泡沫破灭有没有阻碍php发展呢?如果阻碍的话,那别的web技术如asp,jsp也一样被阻碍,最后还是不会影响php的地位。 |
|
返回顶楼 | |
发表时间:2006-09-17
cookoo才是我的知音呀
|
|
返回顶楼 | |
发表时间:2006-09-17
我个人认为,在目前流行的语言中,Ruby 可能是设计得最好的语言。所以才可能出现 Rails 这样优雅的框架。
要说 Ruby 的障碍,最大的应该是来自日本这个非英语国家。 至于 mixin , 我认为这是非常实用非常漂亮的设计。相对于 C++的多重继承和 java 的接口继承,mixin 机制实在是漂亮。 因为现实世界中的对象具有相当复杂的多面性,而这种多面性出现在语言中往往是通过修饰性的定语或形容词来表示、来限定。这种限定是灵活多变的,而继承,总的来说,是一种死板的分层和分类机制,不适合于用于表示这种灵活的东西。Java 的接口在我看来正是为了解决这种问题, 但它很做作,很不自然。mixin 在我看来是最自然的机制。 我大胆猜想,为了表示作为教师的他,作为学生的他,作为经理的他 这一类的问题。能不能在 Ruby 中提供一种退化机制,把类退化为模块,使得它可以被mixin 到另一个类中。 |
|
返回顶楼 | |
发表时间:2006-09-17
现在,OO设计里面,继承都是不推荐的。多重继承的设计更加很少出现了。 mixin当然比c++多重继承漂亮,也比java的包含一个接口,然后delegate这个接口的所有方法好的多。 好是好。但是,一旦出现了mixin,就意味着这部分的设计对应C++的多重继承。而多重继承应该是作为反模式尽量避免的,不得已才使用的。 不能说,动态语言多么强悍,只需要考虑hack,根本不用考虑其他语言的任何设计原则。这个和UML无关,UML表达Java也不足够。 另外,这个module = class的想法不错。 我也觉得,如果ruby的module,class的概念统一起来,整个语法结构和概念就会简单一些。 module可以相当于partial class, inner class, local class。 |
|
返回顶楼 | |