Do Collections.unmodifiableXXX方法是否违反LSP? [英] Do Collections.unmodifiableXXX methods violate LSP?

查看:147
本文介绍了Do Collections.unmodifiableXXX方法是否违反LSP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Liskov替换原则 SOLID 。我已经读了这个原则一些次,现在已经尝试了解它。

Liskov Substitution principle is one of the principles of SOLID. I have read this principle some number of times now and have tried to understand it.

这是我所做的,



类层次中的强行为契约。

This principle is related to strong behavioral contract among the hierarchy of classes. The subtypes should be able to be replaced with supertype without violating the contract.

我已经读过一些其他文章,我有点失去思考这个问题。

I have read some other articles too and I am a bit lost thinking about this question. Do Collections.unmodifiableXXX() methods not violate LSP?


换句话说,当通过其基类接口使用对象
时,用户只知道基本的前提条件和后置条件
类。因此,派生对象不能期望这样的用户服从比基类所要求的更强的
前提条件

In other words, when using an object through its base class interface, the user knows only the preconditions and postconditions of the base class. Thus, derived objects must not expect such users to obey preconditions that are stronger then those required by the base class



为什么这么想?



之前

Why I think so?

Before

class SomeClass{
      public List<Integer> list(){
           return new ArrayList<Integer>(); //this is dumb but works
      }
}

>

After

class SomeClass{
     public List<Integer> list(){
           return Collections.unmodifiableList(new ArrayList<Integer>()); //change in implementation
     }
}

我不能改变 SomeClass 将来返回不可修改的列表。编译将工作,但如果客户端以某种方式试图改变 List 返回,那么它会在运行时失败。

I cannot change the implentation of SomeClass to return unmodifiable list in future. The compilation will work but if the client somehow tried to alter the List returned then it would fail at runtime.

这是为什么Guava为集合创建了单独的 ImmutableXXX 界面?

Is this why Guava has created separate ImmutableXXX interfaces for collections?

这不是直接违反LSP还是我完全错了?

Isn't this a direct violation of LSP or I have totally got it wrong?

推荐答案

说每个子类必须遵守与超类相同的合同。是否为 Collections.unmodifiableXXX()的情况取决于此合约的格式。

LSP says that every subclass must obey the same contracts as the superclass. Wether or not this is the case for Collections.unmodifiableXXX() thus depends on how this contract reads.

Collections.unmodifiableXXX()返回的对象在尝试调用任何修改方法时抛出异常。例如,如果调用 add(),将抛出 UnsupportedOperationException

The objects returned by Collections.unmodifiableXXX() throw an exception if one tries to call any modifying method upon them. For instance, if add() is called, an UnsupportedOperationException will be thrown.

add()的一般合同是什么?根据 API文档是:

What is the general contract of add()? According to the API documentation it is:


确保此集合包含指定的元素(可选
操作)。如果此集合由于
调用而更改,则返回true。 (如果此集合不允许重复且
已经包含指定的元素,则返回false。)

Ensures that this collection contains the specified element (optional operation). Returns true if this collection changed as a result of the call. (Returns false if this collection does not permit duplicates and already contains the specified element.)

合同,则实际上不可修改的变体不能在可以使用集合的所有地方使用。但是,规范继续并且还说:

If this was the full contract, then indeed the unmodifiable variant could not be used in all places where a collection can be used. However, the specification continues and also says that:


如果集合拒绝添加特定元素的任何原因
它已经包含元素,它必须抛出一个
异常(而不是返回false)。这保留了不变量
,在集合总是包含指定的元素之后,
调用返回。

If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns.

允许实现具有不将 add 的参数添加到集合的代码,但会导致异常。当然,这包括对收集的客户的义务,他们考虑到(法律)可能性。

This explicitly allows an implementation to have code which does not add the argument of add to the collection but results in an exception. Of course this includes the obligation for the client of the collection that they take that (legal) possibility into account.

因此行为子类型(或LSP)仍然满足。
但是这表明如果一个计划在子类中有不同的行为,那么在toplevel类的规范中也必须预见。

Thus behavioural subtyping (or the LSP) is still fulfilled. But this shows that if one plans to have different behaviours in subclasses that must also be foreseen in the specification of the toplevel class.

好的问题,方式。

这篇关于Do Collections.unmodifiableXXX方法是否违反LSP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆