Java中组合爆炸的例子?

时间:2017-06-02 09:22:56

标签: java effective-java

在Effective Java,Item - 18中,Bloch说接口可以防止组合爆炸,这种情况会在类型系统中使用具有多个属性的抽象类时发生。

我无法围绕组合爆炸究竟是什么。

任何人都可以提供组合爆炸的例子,因为使用抽象类,以及如何使用接口来防止这个问题?

2 个答案:

答案 0 :(得分:0)

  

如果类型系统中有n个属性,则可能有2个属性   您可能需要支持的组合。这就是所谓的   组合爆炸。膨胀的类层次结构可能导致膨胀   包含许多方法的类只在其类型上有所不同   论证,因为类层次结构中没有类型可以捕获   共同的行为。

与无法扩展多个类的接口相比,抽象类的一大缺点。

例如,您可以使用接口

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):
}

使用抽象类,您Song compose(boolean hit)重复,并且对此代码的支持非常困难。该系统不如界面使用那么强大。

答案 1 :(得分:0)

注意:此答案来自Software Architecture Design Patterns in Java,有关组合爆炸的示例,请参见装饰器模式一章。

假设您有一个Logger接口和三个具体的实现:FileLoggerSTDOUTLoggerDBLogger。现在想象一下,有3种可能的格式可以记录行:PlainHTMLEncrypted

天真的可以为每种可能的组合创建一个类,总计3 * 3 = 9

  1. FileLoggerPlain
  2. FileLoggerHtml
  3. FileLoggerEncrypt
  4. STDOUTLoggerPlain
  5. STDOUTLoggerHtml
  6. STDOUTLoggerEncrypt
  7. DBLoggerPlain
  8. DBLoggerHtml
  9. DBLoggerEncrypt

上面的9转换为Java中的9种类型。注意导致支持每种组合的类的激增。您可以改用记录器介质(文件,STDOUT,DB)和格式(普通,HTML,加密)创建可重用类型。请注意,此结果仅包含6种类型。然后,您可以使用Decorator之类的模式将记录器类型包装为格式类型(例如,EncryptLoggerDecorator包装DBLogger或包装STDOUTLogger)以动态更改系统的行为,而不是静态地如果要使用use肿的类层次结构,请定义行为。我相信Joshua Bloch试图推动的重点是保持层次结构平坦,而Java接口为此很好地发挥了自己的作用。

相关问题