Oop 使用多态性代替开关
逻辑如下: 服务器准备要通过HTTP响应发送的文件(如index.html或某些.pdf)。根据后缀,我想在HTTP头中设置内容类型 现在的逻辑是我有一个Filetype类,有很多特定的Filetype子类扩展它。但我仍然需要使用“switch”来识别后缀。比如: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
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
语句或开关
)来创建适当的实例。搜索工厂模式以了解更多信息。可能重复的