分类目录归档:Programming

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

 

软件工程方法学

sjji

「方法」,谈的是 How,如:搜集资料、进行推论、解释与预测的工具或技巧。

「方法学」,指的是:研究「方法」的理论。也是研究过程的哲学。

所涉及的主要是(科学研究)方法的基本假设、逻辑与原则,谈的是 What、Why。

以论语中的「杀鸡焉用牛刀」为例:

「方法学」谈的是:
杀鸡应该用什么刀,
以及为何要用这种刀

「方法」谈的是:
如何使用牛刀

学习方法学,能够让我们知道该如何正确使用工具,避免产生杀鸡用了牛刀的窘境。

此外,学习方法学可以回来指导我们,较正确地选择以及使用各种「方法」。

比如,假设我们遇到的可能不是鸡 …

这时,「方法学」有助于提升我们选择正确的「方法」的机会。

软件工程方法学。

软件工程的方法有很多方面的意义。包括项目管理,分析,设计,程序的编写,测试和质量控制。

软件工程方法可以区别为重量级的方法和轻量级的方法。重量级的方法中产生大量的正式文档。

著名的重量级开发方法包括ISO 9000,CMM,和统一软件开发过程(RUP)。轻量级的开发过程没有对大量正式文档的要求。著名的轻量级开发方法包括极限编程(XP)和敏捷过程(Agile Processes)。

根据《新方法学》这篇文章的说法,重量级方法呈现的是一种「防御型」的姿态。在应用「重量级方法」的软件组织中,由于软件项目经理不参与或者很少参与程序设计,无法从细节上把握项目进度,因而会对项目产生「恐惧感」,不得不要求程序员不断撰写很多「软件开发文档」。而轻量级方法则呈现「进攻型」的姿态,这一点从 XP 方法特别强调的四个准则 — 「沟通、简单、反馈和勇气」上有所体现。目前有一些人认为,「重量级方法」适合于大型的软件团队(数十人以上)使用,而「轻量级方法」适合小型的软件团队(几人、十几人)使用。当然,关于重量级方法和轻量级方法的优劣存在很多争论,而各种方法也在不断进化中。

做个了解。部分内容来自 Wiki

题图:杀鸡焉用牛刀。