8.4.3.2 函数式实现
我们不是把基本操作表示为虚方法,通过派生类来填充,而是把它表示为属性,属性的类型是函数类型,Func<Client, bool>,函数然后由类的用户提供。清单 8.18 显示了QueryDecision 类的实现,以及创建简单的决策树示例。
清单 8.18 模板方法的简单实现 (C#)
class QueryDecision : Decision {
public string Title { get; set;}
public Decision Positive { get; set;}
public Decision Negative { get; set;}
public Func<Client, bool>Check { get; set; } [1]
public override void Evaluate(Clientclient) {
bool res =Check(client); [2]
Console.WriteLine("- {0}? {1}", Title, res ? "yes" : "no");
Decision next = res ?Positive : Negative; | 选择后续分支
next.Evaluate(client); |
}
}
var tree =
new QueryDecision { <-- 构造有根查询的树
Title = "More than$40k",
Check = (client) =>client.Income > 40000, [3]
Positive = newResultDecision { Result = true }, | 描写子树为
Negative = newResultDecision { Result = false } }; | ResultDecision或 QueryDecision
QueryDecision 类表示的是要执行关于客户的另一项检查。如果我们严格遵循模板方法模式,检查可能是虚方法,但我们把它指定为属性[1]。属性的类型是函数,参数为客户,返回布尔值。此函数在检查客户时调用[2],根据结果,代码进入两个可能分支中的一个。当创建决策树时,我们不必为每个检查写额外的类,因为,可以使用 lambda 函数[3],简单地提供基本的检查函数。
这个示例演示了面向对象和函数式概念的高效结合。我们创建的类型可以轻松地成为不可变,因此,这个例子更具函数性。但我们没有这样做,唯一的原因想是使用自动属性,使代码更加紧凑。我们先使用了标准的面向对象的设计模式,再使用C# 3.0 中的 lambda 函数来简化,使这个解决方案是多少有点介于传统的面向对象的解决方案,和用 F# 实现的函数式版本之间。
原文地址:http://blog.csdn.net/hadstj/article/details/41774173