使用多态而不是 Switch

Using Polymorphism instead of Switch

逻辑如下: 服务器准备要通过 HTTP 响应发送的文件(如 index.html 或 some.pdf)。基于后缀,我想在 HTTP header 中设置 Content-type。

现在的逻辑是我有 Class 文件类型,有很多特定的文件类型子类扩展它。但我仍然需要使用 "switch" 来识别后缀。类似于:

Filetype f = null;
if(suffix == "pdf"){
    f = Filetype_pdf(source);
} else if (suffix == "html") {
    f = Filetype_text(source);
}

但我使用继承只是为了避免这些 "if"。对这个问题有什么建议还是应该这样?谢谢

假设您具有以下层次结构:

Filetype
    HTMLType
    PDFType
    TxtType

现在假设每个 classes 都理解 type 消息(不是它们的实例,class)。然后,您可以在 Filetype 中创建一个 class 方法,即 classFor 接收一个参数 extension 并响应处理该参数的 Filetype 的 subclass extensionclassFor 的实现包括枚举所有子class es 寻找其 type 匹配 extension.

的子class

在 Smalltalk 中这看起来像

classFor: extension
    ^Filetype allSubclasses detect: [:cls | cls type = extension]

当然,在detect的实现中某处有一个if消息,但是你的代码没有看到它并且优雅地表达了必须满足的条件。

编辑:

这种方法的美妙之处在于,如果您添加(或删除)其他支持新子class的子class,检测适当子class的方法classFor将不会改变文件类型。这与必须详尽列举所有可能性的 switch 语句形成对比。通过避免 switch,您的代码获得了继续使用层次结构的更新版本所需的通用性。