2016-08-03 44 views
2

目前的设计是冲突里氏替换原则的

  1. SharedFolderFolder一个子类。
  2. SharedFile是带有远程资源URL的File的子类。
  3. Folderadd方法中接受File
  4. SharedFolder只接受SharedFile而不是非共享File
  5. File可以被移动到另一个Folderadd
  6. 用于浏览SharedFolderFolder中的文件的UI基本相同。

add in SharedFile违反了LSP。如何重新组织对象结构,同时允许重用一些UI代码?

+1

您可以定义add方法以不合约的方式保证在所有情况下都可以添加。这样就没有替代失败。 – usr

+0

@usr,你是说文档本身可以满足LSP吗?在这种情况下,即使臭名昭着的[Iterator.remove()](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--)方法也能满足LSP。 – jaco0646

+0

静态类型只是一种以机器可读的方式添加* some *文档的方法。接口契约是任意的。这是你定义的任何东西。不要挂上语法或语言问题。 – usr

回答

3

可以泛化FolderFolder<T extends File>,与add(T),并有SharedFolder extends Folder<SharedFile>

这样,SharedFolder预计只会以另Folder<SharedFile>,但没有任何其他类型的Folder<File>

(如果你的语言允许它。这将在Java中是可能的)

+0

假设他需要能够在变量中存储任何文件夹类型。然后,通用约束信息丢失并且LSP违规返回。 – usr

+0

如果您使用任何文件夹类型,则不能在该文件夹中存储任何文件类型。你不能摆脱通用约束。 – njzk2

3

你的问题有很多可能的答案。这里有两个:

  • Folder基类取出add方法,只有让它暴露File元素的(只读)集合。
  • 删除SharedFolderFolder之间的'是'关系。换句话说,不要让SharedFolder继承自Folder。相反,您可以让SharedFolder成为某种包含Folder(组合覆盖继承)的元数据类。
+0

第一个答案如何满足LSP?该集合是否必须是不可变的?否则,有问题的'add()'方法只是移动到集合中。 – jaco0646

+0

@ jaco0646解决了这个问题,因为基类的使用者将无法调用'add'并插入与派生类合约不兼容的项目。 – Steven

+0

...但大概消费者仍然可以调用'getCollection()。add()',这会在与原始'add()'相同的场景中失败。 – jaco0646