Java中的组合爆炸示例?
在有效的Java项目-18中,Bloch说接口可以防止组合爆炸,在类型系统中使用具有多个属性的抽象类时会发生组合爆炸 我无法理解什么是组合爆炸 谁能提供一个使用抽象类的组合爆炸的例子,以及如何使用接口来防止这个问题 如果类型系统中有n个属性,则可能有2n个 您可能必须支持的组合。这就是所谓的 组合爆炸。臃肿的类层次结构可能导致臃肿 包含许多方法的类,这些方法只在其 参数,因为类层次结构中没有要捕获的类型 常见行为 与不能扩展多个类的接口相比,抽象类的一大缺点是它不能扩展多个类 例如,使用您可以执行的接口Java中的组合爆炸示例?,java,effective-java,Java,Effective Java,在有效的Java项目-18中,Bloch说接口可以防止组合爆炸,在类型系统中使用具有多个属性的抽象类时会发生组合爆炸 我无法理解什么是组合爆炸 谁能提供一个使用抽象类的组合爆炸的例子,以及如何使用接口来防止这个问题 如果类型系统中有n个属性,则可能有2n个 您可能必须支持的组合。这就是所谓的 组合爆炸。臃肿的类层次结构可能导致臃肿 包含许多方法的类,这些方法只在其 参数,因为类层次结构中没有要捕获的类型 常见行为 与不能扩展多个类的接口相比,抽象类的一大缺点是它不能扩展多个类 例如,使用您可以执
public interface Singer {
AudioClip Sing(Song s);
}
public interface Songwriter {
Song compose(boolean hit):
}
public interface SingerSongwriter extends Singer, Songwriter
{
AudioClip strum();
void actSensitive();
}
对于抽象类,您应该执行以下操作:
public abstract class Singer {
abstract AudioClip Sing(Song s);
}
public abstract class Songwriter {
abstract Song compose(boolean hit):
}
public abstract class SingerSongwriter extends Singer
{
abstract AudioClip strum();
abstract void actSensitive();
abstract Song compose(boolean hit):
}
对于抽象类,您有
歌曲合成(布尔命中)
复制,并且支持此代码非常困难。此系统不如使用接口时那么健壮。注意:此答案借用了,有关组合爆炸的示例,请参见装饰图案一章
假设您有一个Logger
接口和三个具体实现:FileLogger
,STDOUTLogger
,DBLogger
。现在假设有3种可能的格式可以记录一行代码:普通的
,HTML
,加密的
很自然,我们可以为每个可能的组合创建一个类,其总数3*3=9
:
FileLoggerPlain
FileLoggerHtml
FileLoggerEncrypt
STDOUTLoggerPlain
STDOUTLoggerHtml
STDOUTLoggerEncrypt
DBLoggerPlain
DBLoggerHtml
DBLoggerEncrypt
上面的9在Java中转换为9种类型。注意支持每种组合的类的激增。您可以创建可重用的类型来描述记录器介质(文件、标准输出、数据库)和格式(普通、Html、加密)。请注意,这只会导致6种类型。然后,您可以使用类似Decorator的模式将记录器类型包装为格式类型(例如,
EncryptLoggerDecorator
wrappsDBLogger
,或wrappsSTDOUTLogger
),以动态改变系统的行为,而不是在使用臃肿的类层次结构时静态定义行为。我相信Joshua Bloch试图强调的一点是保持层次结构的扁平化,Java接口很适合这个目的。或者可以使用组合:一个Logger类,带有两个字段,类似:LogFormatter
(将是PlainFormatter
和HtmlFormatter
和EncryptedFormatter
中的一个)加上LogWriter
。