【发布时间】:2015-04-25 23:45:30
【问题描述】:
我 answered a question 正在关注 ImmutableMap。我建议使用代理模式。
问题在于Map 包含一个put 方法,它会抛出一个UnsupportedOperationException。用ImmutableMap 替换Map 的其他实例会破坏里氏替换原则。不仅如此,还需要声明put和putAll【违反接口隔离原则】
从技术上讲,没有办法用ImmutableMap 替换Map 实例,因为Map 只是一个接口。所以我的问题是:
由于Map 包含put 和putAll 方法,使用Map 接口创建ImmutableMap 是否会被视为破坏LSP?不实现Map 会被视为“具有不同接口的替代类”代码气味吗?如何创建一个遵守 LSP 但不包含代码异味的ImmutableMap?
【问题讨论】:
-
Map.put和Map.putAll(以及remove和clear)被定义为“可选操作”。此外,接口文档中指定了从实现类中抛出UnsupportedOperationException的可能性。 -
@MickMnemonic 但这违反了interface segregation principle,其中指出“不应强迫客户端依赖它不使用的方法”。我将编辑问题以包括它也应遵循其他 SOLID 原则
-
我的意思是,这些变异方法的契约至少在
Map接口中有很好的记录。但是你有一个非常有效的观点;Map接口是一个 fat 接口。或许原本应该拆分成Map和ModifiableMap extends Map。 -
有时你必须做你必须做的事情。由于 Map 到处都在使用,因此您只需将未使用的方法放入其中。如果不发明自己的类型层次结构(您可以做到但没人会提供),您将无能为力。
-
请参阅stackoverflow.com/questions/22050848/…,讨论关于集合变异方法是否违反 LSP 的辩论。
标签: java interface immutability liskov-substitution-principle