【问题标题】:Does Collections.unmodifiableMap (and others) violate SOLID principles?Collections.unmodifiableMap (和其他)是否违反了 SOLID 原则?
【发布时间】:2020-07-26 23:31:13
【问题描述】:

我最近在阅读Java Concurrency in Practice,第一次接触到Collections.unmodifiableMap(...)方法。该方法在现有Map 周围创建一个只读包装器,并且任何修改返回的Map 的尝试都将(根据Javadocs)导致UnsupportedOperationException 被抛出。其他集合类也存在类似的方法。

这让我很担心,因为unmodifiableMap() 仍然返回Map,但不支持所有相关方法。事实上,它还会在写入操作中引发异常,这意味着它不能在大多数应用程序中替换“正确的”Map

我是一名学生,对自己识别设计缺陷的能力还没有信心,但这些是否分别违反了Interface segregationLiskov substitution 原则?

【问题讨论】:

  • 令我震惊的是,它可能不会违反 I 原则,因为这与接口的创建者有关,而不是客户端。
  • Map 接口文档,实现可能选择不支持其所有方法。老实说,这是一种设计妥协,在实践中效果很好。
  • @LouisWasserman 谢谢,我错过了。如果你把它作为一个答案,我会关闭这个问题。

标签: java oop solid-principles


【解决方案1】:

实现可能选择不支持其所有方法的 Map 接口文档,这使得 Collections.unmodifiableMap 返回满足接口契约的实现。

虽然接口以这种方式实现其方法“可选”是不寻常的,但这是一种设计妥协,在实践中效果很好。大多数集合应该只写入一次,然后一次又一次地读取,因此修改映射的代码通常是创建它的代码并且知道它是可变的。

【讨论】:

  • 我更喜欢 MapMutableMap 的分离,后者扩展了前者(与其他集合相同)。可变版本还应该有一个返回只读视图的方法(例如Map<K,V> asReadOnlyMap()),可能返回一个缓存实例(直到实现),以防止在公开所述集合时发生任何向下转换。
  • @Slaw,你可能对blog.codefx.org/java/immutable-collections-in-java感兴趣。
  • @jaco0646 有趣的博客 :) 它基本上以我希望的相同解决方案结束,只是还有一个额外的 immutable 版本的界面(我只是去只读/读写现在与不可修改的集合相同,只是不会混淆只读引用中存在的mutator方法)。不幸的是,尽管我同意海报的观点,即这将永远不会在 Java 中实现,因为它破坏了向后兼容性。
  • 第一个实际出现的问题是MutableMap.keySet的类型,它可以支持删除但不支持添加,或者Arrays.asList,它支持set但不支持add或@ 987654330@。在显式接口中捕获该级别的详细信息很快变得不切实际。
  • @Louis 是的,仍然存在一些问题,并且仍然需要记录一些方法才能抛出UnsupportedOperationException,但我更喜欢这种“半措施”而不是完全缺乏阅读-唯一/不可变的集合类型。
【解决方案2】:

关于 ISP,Bob Martin 可能会认为 Collections.unmodifiableMap() 会产生与他的 stack class example 相同的违规行为。它将客户端暴露给他们不需要且实际上无法使用的接口。

如前所述,接口文档满足 LSP。

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多