【51CTO独家特稿】设计模式再“高级”一点,便是所谓的“框架”了。

从事Web开发,一般都会接触到MVC框架这个概念。

M:也就是Model,直接跟网站数据库相关。

V:也就是View,是网页的模版,跟显示数据相关。

C:则是Controller,相当于网站的业务逻辑。

MVC也不仅仅是应用于网站开发,它的概念实际上植根于桌面软件,并且在手机软件开发上也有应用。

MVC本身是一个设计模式,是一个被验证过的,可以用来很好归纳、管理代码的软件开发方式。

基于这样的设计模式,提供了很多相关的类库实现,则“设计模式”升级为“框架”。

MVC的任何一个方面,扩展出去讲,都可以讲上几天几夜。

今天只讲V。

传统的ASP / PHP网站开发,V是很混乱的。

默认只有一种文件,html与业务逻辑代码混杂在同一个文件;相当难以维护。

ASP.NET相对于asp做出了很大改进,提出了code-behine的概念:默认将html的模版代码,以及c#或者vb.net的逻辑代码切分到两个不同的文件。

这样的方式算是有很大进步。

微软平台上做开发是比较苦逼的,微软掌控了整个开发平台的前进速度。

asp跟PHP在开始的时候,是相似的技术。有类似的便利,以及类似的麻烦。

微软推出了.net,推广了code-behind的模式;然后,所有的微软程序员都超着微软指定的这个方向去迈进。

asp被抛弃了,自从ASP.NET诞生之后,就不再有任何改进。

而PHP,在开源世界中,则不断的得到各式各样的改进。

各种模版引擎层出不穷;不仅可以实现code-behind这样简单的模版、业务代码分割;很多还直接引入了MVC的概念;实现了三层的分割。

而ASP.NET,则长期止步于web form的code-behind,在开源世界中的MVC方案大放光彩若干年后,才推出 ASP.NET MVC。

模版技术,最初的目的就是要把业务代码,也就是说,把获得数据的代码跟html分割。

在模版实现上,因此涌现了不少不同的设计哲学。

Python的Django框架中的模版,是一种典型。

它彻底的禁止程序员在模版中嵌入任何代码;模版中,只可以出现html;以及一些跟业务逻辑无关的控制标签,如:

  1. {% If XXXX %} foo {% else %} bar {% end %}

条件XXXX,必须是一个数据值,不可以是一个复杂表达式、不可以包涵函数调用等等。

模版中,也不可以声明任何新的变量,下面的做法是被禁止的:

  1. {% set i = 0 %}
  2. {% foreach item in items %}
  3. {% i += 1%}
  4. <div>
  5. ` item `
  6. {% if i mod 2 == 0 %}
  7. <hr />
  8. {% end %}
  9. </div>
  10. {% next %}

Django的模版,从技术上彻底禁止程序员添加任何逻辑,强迫程序员必须在controller中去写各种逻辑,以确保模版内容的纯洁干净。

所以Django的模版,一般都非常简单,有很好的移植性,并且可以让网页设计人员直接编辑。

ASP.NET则是另一种典型;虽然有了code-behind,但是它没有对前端代码,以及后端代码做任何限制。

在前端aspx页面中,可以嵌入任意的逻辑代码,而code-behind的code,为空白;这种伪“code-behind”的方式,跟原来的asp没啥区别。

ASP.NET从框架本身,并不阻止程序员去做这样的事情,实际上,它还标榜它这样的特性:方便原有的asp项目直接升级到.NET的平台上。

也有另外一种奇葩的做法,前端aspx页面保持空白,然后在code-behind的code中去拼接所有的html。这样的方式,ASP.NET框架本身也不禁止。

只要ASP.NET程序员喜欢,没有什么不可以的。

ASP.NET把对模版使用方式的选择权留给了程序员,如果程序员自律,他们可以按Django模版那样的方式去使用模版,并拥有Django一样的优点;如果程序员自律?!

在某些可以通过嵌入代码去快速处理的场景,ASP.NET的模版也保留了程序员去hack的能力。

还有一些模版技术,则是折衷的(如tornado的模版):允许嵌入单行代码,如声明变量,调用函数等等;但是不允许整块、整块的业务代码出现模版中。

上述三种模版设计哲学,各有它们的道理,以及应用场景。

需要根据具体的业务、应用场景,才能说其中哪种比较合适。

开发人员的能力也是直接相关的,如果团队中,普遍不自律;缺乏将业务、模版代码分割、以提高代码可维护性的意识,那么Django的做法是最好的,它直接禁止去滥用模版,强迫他们去使用更好的开发风格;即便在某些场景下会更麻烦。

武断的认为任何一种模版设计哲学是“最佳”的想法是极其肤浅的。

各种成熟的模版技术,一般也都会有包括以下特性:

1. 嵌入

也就是说,编写各种可以复用的小模版块,然后供多个不同地方调用;比方说,用户头像(甚至名片)的显示。

具体页面不需要重复编写这些重复的模块。

并且,这些模块需要调整时,只需要修改一个地方,便可以在所有地方生效。

2. 继承

能够编写一些基础模版,定义常见的页面结构。

具体页面继承这些基础模版,便不需要重复编写那些结构代码。

同样的,当页面结构需要调整时,也是修改一处,所有生效。

3. i18n

网页模版的国际化支持是一个模版引擎是否成熟的表现。

如果没有,当网站需要同时提供多种不同语言支持的时候,会很麻烦。

成熟的模版,都会提供内置的支持。

因为网页模版实现实在是太多了,大家功能也都差不多,那么性能,也就成为了相当重要的比较指标。

有的模版,能够“编译“,渲染起来快些。

一般可以简单认为,功能越多的模版,性能会约低。有的模版,甚至将i18n的支持变成可配置的,不需要的时候就可以关闭,以提高性能。

也有的模版认为,写 {% %} <%%> {{}} 这样的符号太麻烦了,可以直接忽略,它可以自动聪明的识别 html,以及模版控制代码。简单的说,就是以极其华丽的方式,去方面程序员少打几个字符。

还有的模版,在实现嵌入功能的时候,还可以选择所依赖的的css / js文件。

比方说,要显示用户的名片,需要引入 namecard.css;那么,可以在 namecard的模块文件中指定这个依赖,然后模版渲染的时候,自动把这个css的引用,放在html的头部。

直接在模块文件中写 namecard.css 的引用是很傻的,因为模块可以在模版中引用多次。重复引用同一个css文件是没有道理的。

种种模版功能细节,实际上,都是可以在没有模版支持的框架中去实现。

想想PHP,它本来是非常简单的,默认只能够在同一个文件中混杂逻辑与代码。

但一旦程序员有了追求,它也可以有模版实现。

模版不支持 i18n,程序员一般也是有办法在现有模版实现中添加相应的支持的。

并不复杂,关键是看程序员的态度;看程序员是否有把事情做得更好、更优雅的态度。

一般情况下,程序员选择去实现更多的模版功能的时候,必须先看看别人是怎么做的。比方说,如果完全不知道什么是gettext就去自行实现模版的 i18n 功能,是非常2B的。

绝大多数情况下,程序员面临的问题,都不是自己独有的,一定是别人已经解决过的问题。

是否有足够的见识,有足够的知识广度,了解别人的解决同样问题的做法是程序员能力的表现。

是否有快速的搜索出类似的解决方案,也是能力的表现。

1. PHP的Smarty 模版的设计哲学是什么?

2. Perl的Mason 模版的设计哲学是什么?

3. 什么是gettext?

4. 前端Javascript实现的模版中,目前最成熟的是哪个引擎?

男主角:Wuvist(新浪微博),真名翁伟,自称胖程序员一个,幸好已婚。学习.NET出身,现常用Python做服务器端开发,曾任新加坡某创业公司主程。公司被Techcrunch blog过后,觉得新加坡生活太过安逸,终于在去年辞职只身回家乡汕头创业,活跃于珠三角技术沙龙,热衷于与其他技术宅分享。

Wuvist

本文作者:Wuvist

女主角:Katze,Wuvist的老婆,女程序员,在某跨国投行任Unix系统管理员,常被Wuvist嘲笑技术太差。

51CTO系列:

  1. 宅男程序员给老婆的计算机课程之0:认清本质
  2. 宅男程序员给老婆的计算机课程之1:认清实际
  3. 宅男程序员给老婆的计算机课程之2:怎么看待牛人
  4. 宅男程序员给老婆的计算机课程之3:架构比较
  5. 宅男程序员给老婆的计算机课程之4:SQL vs NoSQL
  6. 宅男程序员给老婆的计算机课程之5:设计模式
  7. 宅男程序员给老婆的计算机课程之6:模版引擎
  8. 宅男程序员给老婆的计算机课程之7:运维的重要性
  9. 宅男程序员给老婆的计算机课程之8:控制器
  10. 宅男程序员给老婆的计算机课程之9:数据模型
  11. 宅男程序员给老婆的计算机课程之10:做,就对了!
  12. 宅男程序员给老婆的计算机课程之11:域模型