如何编写一个遵循Liskov替换和其他SOLID原则的不可变映射而没有代码味道?

问题描述 投票:4回答:1

我qazxsw poi关于qazxsw poi。我建议使用代理模式。

这个问题是answered a question包含一个ImmutableMap方法,它将抛出Map。用put取代UnsupportedOperationException的其他实例将打破Liskov Subsitution原则。不仅如此,需要声明MapImmutableMap [违反界面隔离原则]

从技术上讲,没有办法用put替换putAll实例,因为Map只是一个接口。所以我的问题是:

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

java interface immutability liskov-substitution-principle
1个回答
1
投票

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

实现Map的类必须实现put并不理想,但是替代方案可能是具有复杂的接口层次结构,每个接口只包括可能的可选方法的子集。如果有Map可选方法,则必须有put接口来覆盖所有组合。我不知道n的值,但是有一些非显而易见的可选操作,例如2^n返回的n是否支持Iterator操作。如果你将这个层次结构与实际已经存在的接口和抽象类的层次结合起来(包括map.entrySet().iterator()setValueAbstractMapSortedMapNavigableMap ......),那么你就会陷入混乱。

所以没有完美的答案,但在我看来,最好的解决方案是让ConcurrentMap实现ConcurrentNavigableMap并确保你用ImmutableMap作为参数编写的每个方法都清楚地记录了Map必须具有的任何属性以及如果错误则抛出异常通过Map的类型。

© www.soinside.com 2019 - 2024. All rights reserved.