answered a question重新设置ImmutableMap。我建议使用代理模式。

问题是Map包含put方法,该方法会抛出UnsupportedOperationException。用Map替换ImmutableMap的其他实例将破坏Liskov替换原则。不仅如此,还需要声明putputAll [违反了接口隔离原则]

从技术上讲,由于Map只是一个接口,因此无法用ImmutableMap替换Map实例。所以我的问题是:

由于ImmutableMap包含MapMap方法,是否会考虑使用put接口创建putAll打破LSP?是否将实现Map视为“具有不同接口的替代类”的代码味道?如何创建一个遵守LSP但不包含代码味道的ImmutableMap

最佳答案

在我看来,ImmutableMap应该实现Map。不实现Map是一个坏主意,因为有许多方法接受Map作为参数,并且仅在只读意义上使用它。我不认为这确实违反了Liskov替代原则,因为Map的合同清楚地表明put是可选操作。

实现Map的类必须实现put是不理想的,但替代方法是具有复杂的接口层次结构,每个接口仅包括可能的可选方法的子集。如果有n可选方法,则必须有2^n接口才能覆盖所有组合。我不知道n的值,但是有一些非显而易见的可选操作,例如Iterator返回的map.entrySet().iterator()是否支持setValue操作。如果将此层次结构与实际已经存在的接口和抽象类的层次结构(包括AbstractMapSortedMapNavigableMapConcurrentMapConcurrentNavigableMap……)组合在一起,您将一团糟。

因此,对此没有完美的答案,但是我认为最好的解决方案是使ImmutableMap实现Map并确保您将Map作为参数编写的每个方法清楚地记录了Map必须具有的所有属性以及如果错误则抛出的异常传递了Map类型。

10-06 09:39