Oop 使用多态性代替开关

Oop 使用多态性代替开关,oop,Oop,逻辑如下: 服务器准备要通过HTTP响应发送的文件(如index.html或某些.pdf)。根据后缀,我想在HTTP头中设置内容类型 现在的逻辑是我有一个Filetype类,有很多特定的Filetype子类扩展它。但我仍然需要使用“switch”来识别后缀。比如: Filetype f = null; if(suffix == "pdf"){ f = Filetype_pdf(source); } else if (suffix == "html") { f = Filetype

逻辑如下: 服务器准备要通过HTTP响应发送的文件(如index.html或某些.pdf)。根据后缀,我想在HTTP头中设置内容类型

现在的逻辑是我有一个Filetype类,有很多特定的Filetype子类扩展它。但我仍然需要使用“switch”来识别后缀。比如:

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

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

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

Filetype
    HTMLType
    PDFType
    TxtType
现在假设这些类中的每一个都理解
类型
消息(不是它们的实例,而是类)。然后,您可以在
Filetype
中创建一个类方法,即
classFor
,它接收一个参数
扩展名
,并响应处理该扩展名的
Filetype
的子类。
classFor
的实现包括枚举所有子类,以查找其
类型
扩展
匹配的子类

在Smalltalk中,这看起来像

classFor: extension
    ^Filetype allSubclasses detect: [:cls | cls type = extension]
当然,在
detect
的实现中有一条
if
消息,但是您的代码没有看到它,并且优雅地表达了必须满足的条件

编辑:


这种方法的优点在于,如果您添加(或删除)其他支持新文件类型的子类,则检测相应子类的方法
classFor
不会改变。这与
switch
语句形成对比,后者必须详尽地命名所有可能性。通过避免使用
开关
您的代码获得了继续使用较新版本的层次结构所需的通用性。

当您实际使用
文件类型
实例时,继承将使您免受
if
的影响。在某些时候,您仍然需要一种方法来检查如何实例化适当的
Diletype
派生类。通常,该任务被委托给一个称为工厂(工厂方法或工厂类)的对象,而这个对象仍然使用某种逻辑(
if
语句或
开关
)来创建适当的实例。搜索工厂模式以了解更多信息。可能重复的