我最近在阅读Java Concurrency in Practice
,第一次接触到Collections.unmodifiableMap(...)
方法。该方法围绕现有Map
创建一个只读包装器,任何修改返回Map
的尝试都将(根据Javadocs
(导致抛出UnsupportedOperationException
。其他集合类也存在类似的方法。
这让我非常担心,因为unmodifiableMap()
仍然返回一个Map
,但不支持所有相关方法。它还会在写入操作上引发异常,这意味着它无法替换大多数应用程序中的"正确"Map
。
我是一名学生,对自己识别设计缺陷的能力还没有信心,但这些不是分别违反了Interface segregation
和Liskov substitution
原则吗?
Map 接口记录了实现可能选择不支持其所有方法的情况,这使得Collections.unmodifiableMap
返回满足接口协定的实现。
虽然接口以这种方式实现其方法"可选"是不寻常的,但这是一种设计折衷,在实践中效果很好。 大多数集合应该只写入一次,然后一次又一次地读取,因此修改映射的代码通常是创建映射的代码,并且知道它是可变的。
关于ISP,Bob Martin可能会考虑Collections.unmodifiableMap()
产生与他的堆栈类示例相同的违规行为。它将客户端暴露给他们不需要的接口,实际上无法使用。
如前所述,接口文档满足 LSP 的要求。