在动态语言中实现访客模式的首选方法?
时间:2020-03-05 18:47:47 来源:igfitidea点击:
作为我自己的练习,我正在将示例程序翻译成多种语言。从C#开始,我有一个访问者模式界面,如下所示:
interface Visitor { void Accept(Bedroom x); void Accept(Bathroom x); void Accept(Kitchen x); void Accept(LivingRoom x); }
转向ruby(或者python或者其他),我不再从编译器根据类型进行分派。我应该在访客本身中调度吗?
class Cleaner def accept(x) acceptBedroom(x) if Bedroom === x acceptBathroom(x) if Bathroom === x acceptKitchen(x) if Kitchen===x acceptLivingRoom(x) if LivingRoom===x end ...
或者我应该在房间的不同专业中进行调度:
class Bathroom<Room def initialize(name) super(name) end def accept(visitor) visitor.acceptBathroom(self) end end
还是在动态语言中使用了另一个首选惯用法?
解决方案
回答
我的建议是使用前一种方法。每种方法都有其优点和缺点。随着房间类型数量的增加,前者变得难以维护。后者随着清洁类型的增加而变得更加困难。
在Ruby中,我们可以尝试
def accept(x) send "accept#{x.class}".to_sym, x end
PS:并非所有动态类型化的语言都无法基于类型进行分派;有些可以推断类型,也可以失败,可以使用强制转换在重载选项中选择正确的方法。
回答
我会选择第二个版本。第一个看起来像访客应该解决的那种代码气味:长if-else-if或者switch-case语句。