漫画第一站
去年这个时候也是8月份,离开了生活9年的福州来到厦门,已整整一年的时间。离开福州的原因,就是不想让自己在安逸中沉沦下去,需要重新寻找技术的激情。来到新公司后,也开始投入老板梦想中的那个伟大CMS的研发工作,至今仍在不断的忙碌。当时的我,对CMS的概念的并不是特别理解,时至今日,我仍然无法很清楚的定义什么才是CMS。CMS是Content Managment System的缩写,意为内容管理系统,但是从这一年以来的了解来说,在很多人眼里,内容管理系统其实就是网站的后台。只不过很多人会开发一个通用的网站开发平台,用于快速构建网站,这个开发平台就称之为内容管理系统。这一年来,也看过许多开源或不开源的内容管理平台,以DNN为例,它虽然号称为CMS,但它实际是一个二次开发平台,建一个一个网站仍然需要开发人员自己开发业务模块插入到平台运行,模块化开发和模块复用可能是DNN最大的亮点。
而我从一开始接手这个项目以来,多站点、多语言、内容通用化存储、可继承等内容管理和网站集群关系一直是我们在开发这个CMS的核心。在我们的CMS中,必须能创建,管理和维护多个网站。这些网站必须是可继承的,可继承的不仅包含内容,还包含网站的页面,程序,皮肤资源,导航关系等构成网站的所有要求。在这些可继承的元素里,必须多态性,保持高度的灵活,可能本地化一小部分元素,可以在不影响网站运行的情况针对子站点的实际情况对从父站点继承过来的数据进行本地化,以达到局部或全局自定义的目的。
做为一名开发人员,我更愿意将以上特点总结为OO特性。面向对象性网站,因为它完全符合面向对象的三个基本特点:封装性,继承性和多态性。首先是封装性,在一个站点内容,页面和模板使用的是本站点内的资源和内容,它并不受子站点或其它外部因素影响(除继承自父站点外);继承性,网站的继承和网站各种元素的继承本身就体身了它的继承性;多态性,是指在子站点继承父站点后,所有的元素在不改变的情况下都可以直接使用,但是当子站点需要对父站点继承过来的内容进行修改时,需要对它进行本地化,然后修改,这样同时可以覆盖父站点继承过来的内容,同时也可以重写新的行为,犹如虚方法的重写一般神奇。在网站间具备继承关系后,那我们在站点间的资源和程序共享就会变得那么理所当然,创建一组具有一定关系的网站会变得如些的轻松。比如:多语言站点,相似网站的快速复制,各种组织架构间的网站集群。
这就是LZ-CMS最核心的部分。在此基础上,我们需要统一规划组织网站将涉及到的各种资源,包含内容结构定义、内容通用化维护和存储、模板定义、页面定义、资源管理、站点皮肤等元素。我们将这些主要的元素划分为三种不同角色的用户来进行管理:开发人员负责整个网站功能的设计,内容结构的定义,页面的设计;前台设计人员,负责模板的设计,资源管理,站点皮肤管理;最终用户,负责进行内容的维护工作。整个系统的导航也是遵从这样的一套方法标准进行组织。除此之外,在LZ-CMS CMS中,集成了基于Lucene.net的全文检索;可定制计划任务的定时任务执行器;简单灵活的URL SEO设置;所见即所得的前台内容编辑(Inline editing);皮肤管理等等。
当然,做为CMS最重要的组成部分,扩展性是也是一个相当重要的指标。因为再通用化的网站,也会属于自己的特定需求。比如数据的提交,数据需要从异构系统中取得等;再有,有一些特定的模块可能需要进行特定的开发,再以一个完整模块做为网站页面中的一部分加入到网站中,比如订单模块。为此,在LZ-CMS中,提供了两种扩展,分别为页面扩展和模块扩展。页面扩展就是针对某个具体页面的功能扩展,如果提交评论数据;模块,就是一个具有完整链接结构的多个页面的组合,等同于DNN的Module。与DNN不同的是,LZ-CMS中开发这些扩展,不管在开发模式、开发效率、部署上都比DNN来的快速,简单,高效。开发LZ-CMS Module等同于开发标准的ASP.NET MVC网站。
LZ-CMS是一个功能强大的系统,单单凭这里的几百个文字远远无法完全,详细的进行介绍。幸好,LZ-CMS是一个开源的系统,并且也提供了比较全面详细的文档供开发人员了解。做为一个开源系统,而里面的大部分代码都是我完成,所以在这里也想从技术方面来谈谈LZ-CMS。
LZ-CMS尽管从代码的编写和架构设计上,并不是很令自己满意,很多代码都存在着各种问题。一方面,也是水平所限;另一方面也是资源和时间的关系。但从技术路线的选择上,在目前看来,还是比较满意的。首先,LZ-CMS是使用ASP.NET MVC架构之上的全新的ASP.NET架构形式,要知道,在去年的这个时候ASP.NET MVC仍然还处于CTP阶段,这对于一个企业开发具有重要意义的产品来说,是一个多么疯狂的决定,幸好老板也是技术出身,也是一位经验丰富的“老”WEB程序员,他对ASP.NET MVC持坚决支持的态度,并且在公司内部极力推广。其次,在LZ-CMS CMS中的使用的各种组件框架完全走的MS路线,ORM使用Entity Framework,还使用到了Unity,Enterprise Library。
在UI方面,使用了Extjs,完全解决了做为开发人员,在表单开发方面的不足,并且通过表单生成引擎,解决使用Extjs之后,需要编写Javascript(JSON)代码来设计表单的尴尬,要知道一个复杂的表单用JSON来表示,可完全不比通过直接写HTML和样式来的简单,而且一旦出错调试起来会让人马上疯掉。表单生成引擎部分,也许会单独提取出来作为一个独立的开源项目提供使用Extjs的使用者,绝对可以大大提高使用Extjs的效率。
整个系统架构以MVC和Extjs为基础之后,传统的WebForm开发和标准的ASP.NET MVC开发模型又全变了,开发人员所面对的就只一种对象JSON,所有的网络传输也全部变成了传输JSON数据。而开发人员也从原来的数据绑定和字段绑定的痛苦中解脱出来,这是我这一年开发中,最为快乐的事情。
在现有的LZ-CMS源码中,有两部分是最为不满意的:一部分就是测试,本来MVC的一个重要意义就是它的可测试性,在MVC项目中,可以很方便的做到测试驱动开发,这将会大大提高软件的质量,而LZ-CMS除了在早期的代码中有一小部分测试之外,后来连这一小部分也被删除了(没有及时同步);另一部分就是Controller的职责问题,在很多人的架构中,肯定会按功能不同进行分层,比如逻辑层。但是这里,如果没有特别必要,我并没有专门去抽取这一层出来。一方面,在很多地方,Controller都只是做数据的查询工作,而使用了Entity Framework后,查询会变得很简单;另一方面,由于序列化JSON的需要,我需要大量用户匿名对象,而如果单独提取一个独立层出来,我就是要额外定义很多相关的POCO实体来对应JSON序列化的需要。所以现在的很多Controller都是“胖”(fat)的Controller,当时在没有必须的情况下,我不认为它们应该被封装,在会被重用的情况下,我才会考虑重构封装。只是在没有足够测试支持的情况下,每次重构我都要承受着巨大的压力。:(
最后,附上LZ-CMS的相关资源:
官方站点:https://1111mh.com/