注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

John's Blog

天空,有梦就可以飞翔!

 
 
 

日志

 
 
关于我

刚走出校园的毕业生,就读计算机网络专业,对网站建设有一定的基础。开始探求Drupal已有一段时间,对Drupal的发展很是看好。现就职于深圳慧衡科技有限公司(intematrix.cn),它是一家专门服务于中国及海外中小企业的网络营销分析和优化服务提供商。 QQ交流群:44581272

网易考拉推荐

Drupal:从面向对象(OPP)角度看Drupal  

2010-03-18 22:07:21|  分类: drupal小话 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Drupal常常被刚接触Drupal的人批评,他们认为面向对象设计的程序架构最好的方法:他们在Drupal代码里很少看到class,他们认为Drupal设计的很低级。这确实是真的,Drupal很少用php的面向对象设计,但是类的利用和面向对象设计并不等价。实际上,Drupal的核心代码利用了面向对象的很多特征,本文从面向对象的角度介绍Drupal,程序员会在Drupal的核心体会到OPP一样的舒适。

当前这样设计的原因

追溯到4.6版的Drupal,没有用到PHP的类设计。这样设计主要有以下原因:

  • Drupal设计的时候PHP5还没出现,PHP4对对象的支持很弱,直到PHP5,才有较大的改进。
  • Drupal的核心高度区块化,每个模块都有自己的函数。如果包含一些没用的代码,PHP性能会下降很多。所有Drupal在每次请求都会加载尽可能少的代码,这是个决定性的因素,尤其是在没有像APC这样的PHP加速缓存的情况下:实际上,每次请求代码的编译基本会花一半的时间。

  • 使用PHP类来实现Drupal构造将是困难的,因为一些先进的面向对象的设计PHP无法支持。例如Drupal的主题系统,依赖类似Objective-C's "categories"的OPP概念,PHP目前是不支持的

在Drupal7中。这一切都将改变,Drupal7只支持PHP5以上版本,目前有少量的模块就是用PHP的类实现的。尽管如此,Drupal的核心代码仍然没有使用类。

Drupal面向对象概念

尽管Drupal缺乏明确声明的类,但是他的设计仍然有许多类的设计范例。系统有许多面向对象的基本特征。我们将着眼于比较流行的定义之一,研究一些办法显示出中心架构的这些特征。

对象

Drupal的好多组件可以看成是对象,一些比较典型的组件模块,主题,节点,用户都被认为是对象。

节点是一个drupal网站的基本内容构建部分,聚合在一起的数据被称为page或story.找个对象的定义在node模块的node_invoke函数中。user对象同样聚合在一起构成了网站的个人账户,个人信息,会话追踪。这两种情况,Drupal将数据存储在数据库里而不是类,Drupal利用关系数据库的支持允许其他模块来继承对象和扩展数据。

模块和主题在许多方面扮演了控制器的角色,模块是个源文件,他将一些相关的函数捆绑在一起并遵循Drupal钩子的定义。

抽象

Drupal的钩子系统是基于抽象接口,它定义了可以被执行的业务或者被模块调用。如果一个模块实现了钩子,它将执行一个特殊的任务或者通过钩子的调用返回特殊类型的信息,调用代码可以执行一项有用的任务而不需要知道模块和钩子是怎么实现的。

封装

同大多数面向对象系统一样,Drupal没有严格限制访问对象的内部运作方式,但通过公约实现了这一点。Drupal是基于函数的,函数共享着同一个命名空间,但是Drupal通过前缀将函数区分开来。遵守这个简单的公约,模块可以声明自己的函数而不会于其他模块冲突

公约通过内部实现定义了类的公共API,内部函数以下划线开头表示不能被外部调用,例如_user_categories就是一个私有方法,user_save是公用方法可以被外部调用。

多态

节点是传统意义的多态,如果一个模块需要显示一个节点,它可以调用node_build()。然后调用drupal_render(),将会得到一个HTML内容。实际的渲染是看你传的什么类型的节点了,传的节点内容不同返回的内容也就不同了,这很类似类的多态性。

更进一步,渲染出来的HTML内容的样子决定于主题的样式,主题也是类似的多态,返回当前激活的主题样式。

继承

模块和主题也可以被认为是类继承他们从一个抽象基类的行为。在主题的情况下,抽象基类的行为是由在theme.inc职能和主题化中的默认启用模块的实现。一个主题既可以覆盖任何界面组件的默认渲染,或让使用默认的呈现。模块同样可以继承任意一个钩子并实现他们。

Drupal的设计模式

Drupal内部许多架构并不是简单的继承和多态,他从使用的软件设计模式而设计的更有趣的功能。在许多开创性的“四人帮详细模式”(伽马,头盔,Johnson和Vlissides)设计模式的书可以看到一些实例Design Patterns book

单件模式

如果我们把模块和主题看做是对象,那么他们遵循单件模式,一般来说,这些对象不包含数据,他们通过一组函数与其他模块独立开来,所以他们可以被看成是单件模式的类。

装饰器模式

Drupal大量使用了装饰器模式,前面讨论过节点的多态性,这只是节点系统的一小部分。更有趣的是,各节点使用挂钩(hook_node_load(),hook_node_view()等),允许任意模块,扩展所有节点行为。

此功能允许的向节点添加各种功能而不需要子类。例如,一个基本的故事节点只有几个相关的数据:标题,作者,正文,以及极少数的元数据。一个常见的需求是要上传的文件,并连接到一个节点,因此也可以设计一个新的节点类型,有故事节点的功能外还附加文件的能力。Drupal的上传模块满足这一更为模块化方式使用API来给予节点请求它的每一个有能力有需要的节点附加文件。

此行为可以被装饰模式模仿,包装左右他们每个节点的对象。更简单,语言,如同Objective - C的支持类别,可增强对所有节点对象的公共基类添加新的行为。 Drupal的实施是一个简单的挂钩制度衍生物与node_invoke存在()

观察者模式

上述活动也类似面向对象设计的观察者模式。观察者模式遍及整个Drupal,作为Drupal的钩子模块,基本上可以登记成为Drupal的对象观察员。例如,当一个修改了Drupal的分类系统,如hook_taxonomy_vocabulary_update可以在所有模块调用的实现它。通过实施挂钩,这些模块已经登记为对象观察员,任何变化可以作为采取行动是适当的。

桥接模式

Drupal数据库抽象层是在一个类似的桥接模式实现的,设计一个需要数据库系统的模块,数据库抽象层为他提供数据库功能,当需要修改数据库逻辑,只需要修改数据库抽象成API,而不需要修改模块。

职责链模式

菜单系统类似一个职责链模式,当一个页面请求时,菜单系统将会决定加载那个模块,验证用户是否有权限,调用哪个函数。要做到这一点,一个消息传递到菜单项对应的请求路径,如果该菜单项无法处理请求,它传递给职责链。这一直持续到,模块拒绝访问用户,或职责链用尽。

命令模式

许多Drupal的钩子使用命令模式,以减少所必需的函数实现数量,传递操作给函数。事实上,挂钩系统本身使用这种模式,使模块没有实现所有的挂钩,而是仅仅实现他们需要的。

为什么不使用类

上面主要讲了Drupal体现的面向对象设计概念。但是Drupal为什么不使用类来实现这些,这是历史遗留下来的问题,我们使用设计模式来弥补。

一个很好的例子是,系统的可扩展性的主题。一个主题的定义要显示在一种特殊的方式界面元素的每一个功能。如前所述,主题继承一个抽象基类,它定义的元素的默认渲染似乎继承。

当一个模块是补充,增加了新的界面元素,将会发生什么呢?该主题应该能够覆盖该元素的渲染,但是如果一个基类已经定义了,新的模块没有办法为基类增加另一个方法。复杂的模式,可以设立仿效这种行为,但Drupal的主题,结构相当漂亮处理的情况使用自己的职能调度系统,在这种情况下,和其他类似的类,表面上似乎是简化税制,最终将使它更加烦琐,难以扩大。

  评论这张
 
阅读(425)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016