- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我answered a question重新考虑 ImmutableMap
。我建议使用代理模式。
问题是 Map
包含一个 put
方法,它会抛出一个 UnsupportedOperationException
。将 Map
的其他实例替换为 ImmutableMap
会破坏 Liskov 替换原则。不仅如此,还需要声明put
和putAll
【违反了接口(interface)隔离原则】
从技术上讲,没有办法用 ImmutableMap
替换 Map
实例,因为 Map
只是一个接口(interface)。所以我的问题是:
使用 Map
接口(interface)创建一个 ImmutableMap
是否会被视为破坏 LSP,因为 Map
包含一个 put
和 putAll
方法?不会将实现 Map
视为“具有不同接口(interface)的替代类”代码味道吗?如何创建一个遵守 LSP 但不包含代码味道的 ImmutableMap
?
最佳答案
在我看来,ImmutableMap
应该实现 Map
。不实现 Map
是个坏主意,因为有许多方法接受 Map
作为参数并且只以只读方式使用它。我不认为这确实违反了 Liskov 替换原则,因为 Map
的契约(Contract)清楚地表明 put
是一个可选操作。
实现 Map
的类必须实现 put
是不理想的,但替代方案是拥有复杂的接口(interface)层次结构,每个接口(interface)仅包含可能的可选方法。如果有 n
个可选方法,则必须有 2^n
个接口(interface)来覆盖所有组合。 n
的值我不知道,但是有一些不明显的可选操作,比如map.entrySet( ).iterator()
支持setValue
操作。如果将此层次结构与实际已经存在的接口(interface)和抽象类的层次结构(包括 AbstractMap
、SortedMap
、NavigableMap
、ConcurrentMap
, ConcurrentNavigableMap
...) 你会一团糟。
所以这个问题没有完美的答案,但在我看来最好的解决方案是让 ImmutableMap
实现 Map
并确保你编写的每个方法都有一个 Map
作为参数清楚地记录了 Map
必须具有的任何属性,以及如果传递了错误类型的 Map
时抛出的异常。
关于java - 如何编写一个遵循 Liskov Substitution 和其他 SOLID 原则而没有代码味道的 ImmutableMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29872004/
我有一个单独的 Customer 模型的 View ,该模型在构造时获取一个客户和客户集合。客户模型的需求是有道理的——它是客户的 View 。收藏的要求……我不确定那是不是一种气味,希望得到反馈!
我试图在不同的风格中使用相同的 activity 名称,并为每种风格安装正确的名称。 build.gradle : android { .... buildscript {
我是一名优秀的程序员,十分优秀!