8.4.3.2 函数式实现

来源:互联网 发布:网球知乎 编辑:程序博客网 时间:2024/05/02 04:23

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# 实现的函数式版本之间。

0 0
原创粉丝点击