Scala设计模式Part I. 创建模式——2.创建者模式

描述

创建者模式的意图是:
将复杂对象的创建与其表现分离,以使相同的创建过程能够创建不同的表现。

GOF的例子是一个RTF文档交换格式的阅读器,这种格式支持多种不同的表现类型,例如ASCII文本以及GUI图形挂件,可以让用户根据需要编辑文本。
下图是该模式的UML。在GOF的例子中,阅读器扮演了下图中Director的角色。每个产品对应了不同的创建者,图中的产品(Product)就是例子中的不同的表现类型。Director使用具体的创建者(图中Concrete Builder)来创建产品的每个部分并通过GetResult汇集最终的结果。在创建过程中,Director提供向创建者提供创建产品所需的输入。在上面的例子中,阅读器从输入流中读取字符,识别应当表现的类型(文本或者图形),并且据此在Builder中调用相应的BuildPart。
如模式意图所述,创建者封装了创建过程,隐藏了不同表现类型的内部数据结构,同时Director能够使用相同的创建过程来创建不同的表现类型。此处通常不存在可以抽象的产品,因为表现类型往往区别很大,无法继承自一个抽象类。

这里写图片描述

分析

创建者意图是封装其自身的创建过程,通过类方法是实现这一目的的合适的抽象机制。创建过程的成果在细节上 有很大差别,只有输入在不同的具体创建者(Concrete Builder)中保持一致。Scala在实现这些概念的时候并没有什么不同,同样是使用方法。我们可以尝试使用抽象类型来表示构建过程的互相依赖,但是因为输出差别太大,这样做意义不大。
GOF例子中初始的代码使用了双重分派。Director类包含了一个switch声明,对不同的输入种类提供不同的分支处理,调用创建者不同的构造方法。下面的C++模式的例子中t.Type作为switch声明的控制表达式,它必须是整数类型,所以不能使用真实的类型,只能是t对象的一个属性。

switch t.Type {
CHAR: builder->Convertcharacter(t.Char);
FONT: builder->ConvertFontChange(t.Font);
}
//多重分派
builder->Convert(t)

当然这需要两个都为Convert名称的方法,都通过一个参数提供不同的类型。注意后一个t与前一个个t的类型是不同的。

Scala的模式匹配功能可以轻松实现多重分派

t match {
  case c@ Character()=>convert(c)
  case f@ Font()=>convert(f)
}

def convert(t:Font)=println("Convert font")
def convert(t:Character)=println(Converting character")

使用Scala的模式匹配技术,匹配运行时类型,而不是类中用作描述类型的成员。因此也无须再使用多重分配builder->Convert(t),这比本来的代码更好。

模块化

实例化之间的不同之处是在不同的创建者中被封装的创建方法,以及创建的产品和每个创建方法的输入。对类的一些列方法进行抽象是不可能的,这表明了无法对创建者进行模块化。因为不能为依赖于创建者细节的其他的角色提供任何模块。

小结

GOF提出的创建者的解决方案得益于多重分派(double dispatch),但Scala并不能直接提供这一特性。分析表明多重分派可以被Scala的模式匹配代替。
与主流的面向对象语言相比,Scala没有为实现此模式提供新的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值