【问题标题】:java generics heaviness due to design choice由于设计选择导致的 java 泛型沉重
【发布时间】:2013-03-23 13:28:44
【问题描述】:

我有以下学习类,我想成为通用类:

public abstract class Study<
    T1 extends Context, 
    T2 extends Region,
    T3 extends Domain<T2>, 
    T4 extends Solution> {...

派生类的示例如下:

public class AmericanCultureStudy<
    T1 extends AmericanCultureContext, 
    T2 extends AmericanCultureRegion,
    T3 extends AmericanCultureDomain<T2>, 
    T4 extends AmericanCultureSolution>
extends Study<T1, T2, T3, T4> {...

public class ContemporaryAmericanCultureStudy<
    T1 extends ContemporaryAmericanCultureContext, 
    T2 extends ContemporaryAmericanCultureRegion,
    T3 extends ContemporaryAmericanCultureDomain<T2>, 
    T4 extends ContemporaryAmericanCultureSolution>
extends AmericanCultureStudy<T1, T2, T3, T4> {...

public class ContemporaryMainstreamAmericanCultureStudy<
    T1 extends ContemporaryMainstreamAmericanCultureContext, 
    T2 extends ContemporaryMainstreamAmericanCultureRegion,
    T3 extends ContemporaryMainstreamAmericanCultureDomain<T2>, 
    T4 extends ContemporaryMainstreamAmericanCultureSolution>
extends ContemporaryAmericanCultureSolution<T1, T2, T3, T4> {...

这种设计的后果是主代码中类的实例化变得繁重,如下:

ContemporaryMainstreamAmericanCultureStudy<
    ContemporaryMainstreamAmericanCultureContext, 
    ContemporaryMainstreamAmericanCultureRegion,
    ContemporaryMainstreamAmericanCultureDomain<
        ContemporaryMainstreamAmericanCultureRegion>,
        ContemporaryMainstreamAmericanCultureSolution> 
    study = new ContemporaryMainstreamAmericanCultureStudy<
        ContemporaryMainstreamAmericanCultureContext,
        ContemporaryMainstreamAmericanCultureRegion,
        ContemporaryMainstreamAmericanCultureDomain<
            ContemporaryMainstreamAmericanCultureRegion>,
        ContemporaryMainstreamAmericanCultureSolution>() ;

Study 中包含的所有类虽然不同,但都属于相同的关注类型,因此必须有一种方法可以通过减少 Study 发布的类型数量来减轻这种负担。

有人可以帮忙吗? 谢谢

【问题讨论】:

  • 尝试使用更短的类名,命名空间的包...
  • 需要泛型吗?不知道具体实现就不能直接使用interface或者超类吗?
  • 没有足够的信息来理解您要解决的问题,但从类名来看,您可能会将继承与组合混淆。看来ContextRegionStudy 的属性。见stackoverflow.com/questions/11031843/inheritance-vs-composition
  • 看起来你通过子类型和泛型“多态化”了整个对象图。当需要更改某些内容时,您可能会遇到可维护性的噩梦。但仅从类签名很难猜测实际设计可能是什么。

标签: java generics architecture


【解决方案1】:

在这种情况下是否真的需要泛型?例如,是否有可能在您的构造函数中接收一组从ContextRegionDomainSolution 派生的类的对象?如果可以,那绝对是正确的方法。

如果这不可能,您至少可以通过创建一个中间 Culture 类来隐藏一些沉重:

class Culture<
    C extends Context, 
    R extends Region,
    D extends Domain<R>, 
    S extends Solution> {
  ...
}

您需要一个凌乱的声明,例如 ContemporaryAmericanCulture,但您的 Study 实例化可能是 Study&lt;ContemporaryAmericanCulture&gt; study = new Study&lt;ContemporaryAmericanCulture&gt;()

【讨论】:

    【解决方案2】:

    在某些时候,动态地做一些事情是值得的,比如将如下所示的外部表存储在文件或数据库中:

    |ID    | Context | Region | Domain | Solution |  
    |123   | Abc     | Def    | Ghi    | Jkl      |  
    ...
    

    然后您可以为这些实体定义操作/数据,例如打印时使用什么字体、应该重定向哪个页面、允许多少学生参加研究等等。

    你的对象看起来像

       class Study {
           int id;
           String context;
           String region;
           String domain;
           String solution;
       }
    

    类型安全性很好,但如果您想管理许多和/或不可预见数量的实体,那么您不应该以每次添加/更改/删除实体时都需要触摸代码的方式进行编码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多