现在心情很差,头脑很乱,会写得有点语无伦次。
我的需求很简单:
如:有个实体名叫Product,我需要:提供一个网站后台管理,卖家管理,顾客管理,分别对这个实体crud操作。命名方式我是想这样:com.lugua.admin.ProductController,com.lugua.seller.ProductController,com.lugua.customer.ProductController
先用我最熟悉的grails。grails的文档没明确说控制器不能同名,但实际上在grails中用以上的命名,编译是不会出错,当grails按照约定找控制器的时候,就只会去找其中一个,具体找哪个我还没有研究,总之只会去找一个,那这样问题就大了。我不想用AdminProductController,SellerProductController,CustomerProductController这么丑恶的名字来命名控制器。我把grails的UrlMapping文档来回看了很多遍,尝试各种7股8怪的映射方式,无所不用其极,还是没能解决控制器查找重名的问题。于是我想看看通过grails源码能不能找到可以切入的地方。
grails的整个view层就是一个springmvc应用,刚开始确实找到切入点。grails处理控制器的方式大概是:
它会为每个*Controller.groovy控制器注册一个描述的类,这个类用来描述该控制器的uri,与action的对应关系,action与返回的view的对应关系,于是想到在控制器中自己加个static namespace='/admin',在容器启动的时候,通过反射将namespace值追加到uri与view的前面,这样或许可以解决问题。但由于这些对应关系对是用private Map的形式声明的,这么强行写入,可能会破坏数据,事实证明,这么一改,牵一动百。这么一改,牵连到grails处理请求的过滤器,缓存,热部署等等的连锁反应,总之就是不大改,行不通。我可没功夫改这么多了。难怪,我到grails社区论坛上,看到有人提到这问题的时候,社区的反应是,这功能不加是因为想保持grails的简单。我想不是简单吧,是怕牵一动百吧,NND,玩不下去了。
不过这次追逐过程,倒是对grails的请求处理过程有了更深的理解,也增加了但心,因为就我眼看到的源码,有约8个地方用到了反射,对uri的解析映射到控制器action的映射的处理稍显复杂,很是但心性能啊。
不知道play!是不是一路货色,如果能解决这问题,我就用play!开发下一项目。play!最近的呼声很高,不会让我失望吧,我想。
之前没玩过play!,得看个把小时的文档。慢慢发现,它某些地方比grails还省事。并且controller都是静态方法,既然这样,就可能通过com.lugua.admin.Product.show的方式直接引用,应该可以解决我的分包问题。事实上,它确实解决了。定义一个controllers.lugua.admin.Product,通过url/admin/product/show,它就会去找views下面的/admin/product/show页面,一阵兴奋。。。。。
别急,郁闷开始了,当我在项目中引入security这个module的时候,出现问题了。它的权限模块控制器也都是静态方法,并且提供的方式是@Secure之类的注解方式,还有个什么Secure.connected()返回一个登录用户的用户名,当我要修改它的登录逻辑时,当我写个Admin放到controller.lugua.admin包下,用这模块时,连编译都不通过了。因为Secure是Security的内部类,并且不是public的,而是包级的访问声明,也就是default的方式,Security是打包在controllers下,即package controllers,现在明白我要说什么了吧,也就是我的Admin没法引用到这个Secure!!!!!!搞到这里,我发扬不抛弃,不放弃的精神,又折腾了两个小时,最后结果,over,不玩了,没解决问题。也不敢玩了,谁知道再玩下去,还会有什么郁闷的事情呢。
下一站,rails3!,这个呼声更高。rails之前更加没接触过,但是因为之前有grails的基础,还算可以搞一下她。折腾着下个ruby1.9.2,下个rails3,在windows搞好rails开发环境后,开始搞,其中装sqlit3被搞得半死,一开始死活报错,明明gem install sqlit3-ruby装了,并且也提示装好了,起动应用就是报错,老是弄不起来。后来查了半天,是要自己下个sqlit3.ddl丢到ruby_home\bin下面去。看着文档,看到了routes这一块,它里面有个 namespace :admin do products end的示例,这不就是我要的吗???!!赶紧尝试,结果是,bo shift。又是一个表面看起来很美,很华丽的东西。它确实可以分包,但是有限制的。如果是按照以上的路由声明,那么控制器里面的实例变量,也需要如:@admin_product这样的方式,并且对应的model也需要诸如:class Admin::Product的方式声明,否则页面的标签要引用这些变量的时候就会报错。
如果是控制器是如Admin::ProductController这样声明我还忍了,但是model也要求这样,我就没法接受了。Product不属于任何一个命名空间,这么声明意思就是model属于Admin的。
奇丑无比。
不玩了不玩了不玩了,叫你分包叫你分包叫你分包。为了搞这东西,不吃不喝十几小时,中间为了理清思维,还花钱去按了摩洗了脚,杯具。
full-stack。。。。。。,以后别跟我提full-stack这词。。。
回头想,ssh开发效率虽然慢一点,但就是有它强的地方,不会阴碍你架构项目的方式,不会。。。
写这文章不是想误导群众,我是敢肯定grails是不支持的,其它两个框架刚刚接触几小时,反正我是弄不出来了。。。。 写得比较乱,洗洗睡了。