Engines的作用是允许将model,controller和view代码直接嵌入到plugin中,但这其实是同Rails的设计初衷相违背的,这也是为什么DHH反对Engines。Rails针对这种需求提出的解决方案是Generator,相比Generator,Engines让事情变得更简单了一些,使用Engines的好处是,你不再需要生成一堆你可能几百年都不会去看的代码到你的APP目录下,但缺点是一旦你需要对这些代码进行修改,你将不得不再次复制它们到你的app目录下,而且一般来说,这很难避免,并且最终的结果往往是你发现所有代码都需要修改,那为什么不在一开始就用generator将它们全部复制到你的APP目录下呢?
事实上,Generator也不是个好方法,之所以要将代码复制到你的App目录下,而不是放在Plugin中,是因为你需要修改它,而且在大部分情况下你期望对这些生成代码的修改能够复用到不同的项目中,但是使用Generator,你无法复用对这部分代码的修改,而只能一遍遍的重复“生成-修改”的过程,或者从其它项目中copy生成的代码到新项目,但这是个繁琐的过程,John Long在06年的时候就注意到了这个问题,并且他发现Django的解决方案不错,他在05年底的时候帮助组织了Adrian Holovaty(Django之父)和DHH之间的一场讨论,本来他希望看到Django中的一些优秀思想被吸收到Rails中来,但是遗憾的是,这一幕没有发生,直到Rails 2.0,Rails的插件模式并没有发生什么大的变化。
Django的解决方案是将Plugin组织成一个个的mini app而不是Rails的插件,这些mini app同你的app是并列的,要加入一个新的mini app,只需要修改INSTALLED_APPS 即可:
INSTALLED_APPS = (
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,
‘mysite.polls’
)
这样如果你对某个mini app做了修改,在下一个项目中,你只需要将这个mini app直接copy到新项目中即可。
实际上,将Rails的plugin变成Django的mini app也并不难,只需要将Plugin目录变成在development模式下每次重新加载,然后加强路由支持即可,当然更进一步,实际上应该将Rails的插件两类,包含MVC代码的和不包含MVC代码的,John Long已经在Radiant中实践了这个想法,他给包含MVC代码的插件起的名字是extensions。
不过就目前来说,如果你确定你不会修改Plugin中的代码(一般来说发生几率相当小),那么Engines是个不错的选择,否则还是Generator好一些。
参考:

