Template Method Pattern(模版方法模式)

1336965093_1048

在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是某些更细节步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。

在这种情况下,在一个方法中定义一个的算法的骨架,而将一些步骤的实现延迟到子类中,我们称这个方法为:模版方法。

模式结构

抽象类(AbstractClass):定义抽象的原始操作(primitive operation),具体的子类将重定义它们以实现一个算法;实现一个模板方法,在其中定义一个算法的骨架,算法中会去调用原始操作。

具体子类(ConcreteClass):实现原始操作以完成算法中与特定子类相关的步骤。

模式分析

1)是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系;
2)基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一;
3)其关键点是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。

模式优点

1)在一个类中形式化地定义算法,而由它的子类实现细节的处理;
2)是一种代码复用的基本技术。它们提取了类库中的公共行为;
3)形成一种反向的控制结构,通过对子类的扩展增加新的行为,符合“开放封闭原则”。

模式缺点

继承的强制性约束关系也让模版方法模式有不足的地方,我们可以看到对于各个 ConcreteClass 类中的实现的原始方法 Primitive() 是不能被别的类复用的。假设我们要创建一个 AbstractClass 的变体 AnotherAbstractClass,并且两者只是通用算法不一样,其原始操作想复用 AbstractClass 的子类的实现。但是这是不可能实现的,因为 ConcreteClass 继承自 AbstractClass,也就继承了 AbstractClass 的通用算法,AnotherAbstractClass 是复用不了 ConcreteClass 的实现,因为后者不是继承自前者。

适用环境

1)一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2)各子类中公共的行为被提取出来并集中到一个公共父类中以避免代码重复。
3)控制子类扩展。模板方法只在特定点调用原始操作 ,这样就只允许在这些点进行扩展。

相关模式

策略模式:策略模式解决的是和模版方法模式类似的问题,但是策略模式是将逻辑(算法)封装到一个类中,并采取组合(委托)的方式解决这个问题。

实际应用

Zendframework 1.* 中的 Controller 就是用模版方法模式实现的:

父类中的构造函数、dispatch() 都是模版方法,而 init()、preDispatch()、postDispatch() 这些钩子方法就是供子类扩展的。

 

参考:
wiki/Template_method_pattern
http://blog.csdn.net/hguisu/article/details/7564039
http://www.cnblogs.com/phinecos/archive/2006/10/10/524745.html

UML中的依赖关系和关联关系

dependency_association

在 UML 中,依赖关系(dependency)和关联关系(association)都是类之间的横向关系,较难区分,所以我在这里做些整理,以便更好的阅读 UML 类图。

依赖关系(dependency)

阐述:
可以简单的理解,就是一个类 A 使用到了另一个类 B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是 B 类的变化会影响到 A;比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖;依赖关系总是单向的。

表现:
表现在代码层面,如类 B 作为参数被类 A 在某个方法中使用。

实现:
依赖关系体现为:局部变量、方法中的参数,还有对静态方法的调用。

关联关系(association)

定义:
该关系体现的是两个类、或者类与接口之间语义级别的一种强依赖关系;这种关系比依赖更强,不存在依赖关系的偶然性,关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的,可以是双向的。

表现:
表现在代码层面,比如被关联类 B 以类属性的形式出现在关联类 A 中,也可能是关联类 A 引用了一个类型为被关联类 B 的全局变量;

实现:
关联关系是使用实例变量实现的。

两者之间的联系

很多关系(泛化、继承、关联、聚合,等)都包含依赖关系,当这些关系存在时,不需要再额外建立依赖关系。依赖关系强调一个类需要使用另一个类;关联关强调结构,一个类持有另一个类的实例,当有需要时可以自由地使用。

例子

UML参考封面图片

 

参考资料:
What is the difference between dependency and association?
wiki Dependency_(UML)
wiki Association_(object-oriented_programming)
wiki Coupling_(computer_science)
wiki Class_diagram
Dependency & association in UML

 

是 WordPress 让 PHP 更流行了,而不是框架

trends_php

Tiobe Index(编程语言世界排名指数),是一个显示各种编程语言的相对流行趋势的排名,开始于 2001 年,每个月更新一次。它将很多站点的搜索结果计算在内,以得到统计数据。这些站点包括:Google,Blogger,Wikipedia,YouTube,Baidu,Yahoo,Bing,Amazon 等。

PHP 在 Tiobe 上排名一直靠前,但最近它的排名更靠前了,2012 年是第7,现在是第5。人们可能将此归因为去年年底 Zend Framework 2 的发布,但并没有什么依据。

于是作者开始探究为什么 PHP 在 Tiobe 上的排名曲线突然上扬,真的是官方框架发布造成的么?下面是他的结论,我大致翻译如下。

一、WordPress 是最流行的 PHP 应用

作者用 Google Trends 去比较几个关键字的趋势,这些关键词是:WordPress,Joomla,Drupal,Magento,Zend Framework,它们的趋势走势图如封面所示。

介绍下它们。WordPress 是开源博客程序,Joomla 和 Drupal 都是开源内容管理发布系统,Magento 是开源的电子商务程序(国内似乎有家麦神电子商务把它汉化了在卖服务),Zend Framework 是官方开源的 PHP 框架。

最流行的是 WordPress,比其他应用都流行很多,垫底的是 Zend Framework。

其实这些关键词是作者认为最流行的关于 PHP 的词了,我觉得选这些词也是合适的。框架选一个做代表就行,而应用的流行程度差别很大,尽量选名气大的。我在这些词中把 PHP 也加进去,发现 WordPress 的流行程度都快接近 PHP 了,所以说,用“最流行的 PHP 应用”来描述 WordPress 没任何问题。

二、WordPress 自身比任何 PHP 框架要流行的多

这个结论细化了第一个结论。别以为只选了一个框架做比较,其实所有框架都差不多那个数量级。

三、WordPress 没有用第三方框架

为了补充第二个结论…

四、是应用让技术流行起来,而不是框架

趋势图上提到的 Magento 这个电子商务应用,是基于 Zend Framework 开发的,但它比框架流行。所以让应用流行起来的原因,并不是因为它使用了什么框架,而是它解决了用户的实际问题。

WordPress 也是同样道理,它对很多人都很有用。当人们要装个 WordPress 时,他们就知道了 PHP 这门技术,他们需要支持 PHP 的虚拟主机空间。这就促使了 PHP 的流行。

五、可扩展的 WordPress 插件生态

让 WordPress 流行的最重要原因之一就是它的插件系统。插件几乎能做任何事情,它们让 WordPress 成为一个平台,而不仅仅是一个应用。

六、很多非程序员因为 WordPress 开始开发 PHP

很多 WordPress 用户并不是程序员,但是因为找不到合适的插件、主题等,他们开始自己开发这些需求。

七、实用主义比理想主义好

软件项目,在技术上得是美丽的,得是一致的,得遵循良好的项目计划,得赞扬设计模式。

但上面这些真的没想象中的重要。很多应用被创建是基于一种很实际的感觉,它们只专注于解决现实世界的需要。

相对而言,很多 PHP 框架,它们似乎开发自另一个星球。它们常常由理想主义的人开发,更关注设计模式。

 

我的一点总结:

作者还是用确凿的证据证明了他的观点。而我,也从中看到一些要注意的地方:

1、过于注重技术。在开发岗位工作,注重技术是必须的。但是当自己做一个产品时,最应该关注的是解决现实世界的问题。

2、框架,解决的现实问题是,帮助普通开发者基于框架能更轻松快捷地开发应用。相对应用来说,面对的用户量肯定是少几个数量级的。

3、也许,针对某个流行应用提供解决方案或服务,就很有前途。当然,开发出解决现实世界问题的应用,更有前途。