代码之家  ›  专栏  ›  技术社区  ›  Simon Nickerson

是否有理由使用“伪typedef反模式”?

  •  9
  • Simon Nickerson  · 技术社区  · 16 年前

    我有一个相对复杂的通用类型(比如 Map<Long,Map<Integer,String>> )我在课堂上内部使用。(没有外部可见性;它只是一个实现细节)。我想把它隐藏在一个TyPulf中,但是Java没有这样的功能。

    昨天我重新发现了下面的成语,很失望地发现它是 considered an anti-pattern .

    
    class MyClass
    {
      /* "Pseudo typedef" */
      private static class FooBarMap extends HashMap<Long,Map<Integer,String>> { };
    
      FooBarMap[] maps;
    
      public FooBarMap getMapForType(int type)
      {
        // Actual code might be more complicated than this
        return maps[type];
      }
    
      public String getDescription(int type, long fooId, int barId)
      {
        FooBarMap map = getMapForType(type);
        return map.get(fooId).get(barId);
      }
    
      /* rest of code */
    
    }
    

    当类型被隐藏并且不构成库API的一部分时(在我看来,Goetz主要反对使用它),是否有任何理由对此进行解释?

    6 回复  |  直到 8 年前
        1
  •  5
  •   dfa    16 年前

    真正的问题 这个成语是在 伪Type 以及你的客户代码。然而 因为你在使用 FooBarMap 私下里没有真正的耦合问题 (它们是实现细节)。

    一个现代的Java IDE应该有助于处理复杂的泛型类型。

        2
  •  10
  •   Stephen C    8 年前

    IMO,Java反模式的问题是它们鼓励黑白思维。

    实际上,大多数反模式都是细微差别的。例如,链接的文章解释了伪typedef是如何导致API的类型签名过于严格、过于依赖于特定的实现决策、病毒性等等。但这都是在公共API的上下文中进行的。如果将伪typedef排除在公共API之外(例如,将它们限制在类或模块中),它们可能不会造成真正的危害,而且它们 可以 使代码更可读。

    我的观点是你需要 理解 反模式和使 合理判断 关于何时何地躲避它们。只是站在“我愿意”的立场上 从未 做X是因为它是反模式的“意味着有时你会排除可接受的,甚至是好的解决方案。

        3
  •  2
  •   marijne    16 年前

    对于公共接口,我不喜欢看到泛型类型,因为它们没有意义。对于我来说,看到一个参数为hashmap<long、map<integer、string>>的方法很像那些C方法,比如foo(int、int、int、void*、int)等等。拥有真正的类型只会使代码更容易阅读。对于公共接口,最好创建包装hashmap<long、map<integer、string>>的foobarmap,而不是“typedef”,但对于类内部使用,我看不到任何反面。

        4
  •  0
  •   Tadeusz Kopec for Ukraine yespbs    16 年前

    如果没有这个伪typedef,我宁愿写

    private Map<Long,Map<Integer,String>>[] maps;
    

    如果有一天我决定将实现类从hashmap更改为treemap或java7greatenhancedwonderfulmap:-),什么都不会破坏。但是有了这个,你就被哈希图卡住了。好吧,你可以做:

    interface FooBarMap extends Map<Long,Map<Integer,String>> { };
    class FooBarHashMap extends HashMap<Long,Map<Integer,String>> implements FooBarMap{ };
    

    但它变得越来越笨重。

        5
  •  0
  •   Mohammed Arif    16 年前

    当涉及到将它放入公共接口时,他对此有一个很好的观点。这个成语模仿的是某种形式的句法糖分,它不应该影响你向客户展示的内容。

    但是我认为没有什么好的理由不在本地使用它,前提是它使您的生活更容易,代码更可读——而且您知道您在做什么。在任何情况下,布赖恩都可能归纳并强烈反对,但这是他的戈茨感觉:p

        6
  •  0
  •   soru    16 年前

    如果您只在一个小的本地化代码单元中使用它,那么问题很小,是真的。

    事情是,收益也是一样的:在你引用伪typedef 5+次之前,你的程序可能甚至不会变得更小,这意味着它在其中可见的区域必须是不平凡的。

    我可能不会重写这样做的代码,但这似乎是一个坏习惯。