Can I apply here Liskov substitution principle

拈花ヽ惹草 提交于 2019-12-08 00:08:45

问题


I have two data models which are represented by the following classes:

1) ImagesSet - an object that owns 2DImage's, each 2DImage has its own position (origin(3DPoint), x-,y-axes(3DVector) and dimension along x and y axes(in pixels)), but the same pixel size(in mm for example), angle between x and y axes(90 degrees)

This object has following methods(in pseudo code):

  • AddImage(2DImage);
  • RemoveImage(ImageIndex);
  • number GetNumberOfImages();
  • 2DImage Get2DImage(ImageIndex);

2) 3DImage - an objects that is similar to the first but with following restrictions: it can store 2D images only with the same x-,y-axes and dimensions along x and y axes.

Is it correct in this case to derive 3DImage from ImagesSet? From my point of view 3DImage "is a" ImagesSet (but with small restrictions) Could I apply here Liskov substitution principle?

In this case if we are trying to add an image with another x,y axes - method AddImage either will throw an exception or return an error.

Thanks in advance, Sergey


回答1:


I agree with maxim1000 that LSP will be violated because derived class adds restrictions that are not present in the base class. If you take a close look at your description you will notice that the question can be turned upside-down: Can ImageSet derive from 3DImage?

Your situation is somewhat similar to Ellipse-Circle problem. Which one derives from the other? Is circle an ellipse with a constraint, or is an ellipse a circle with additional radius? The point is that both are wrong. If you constrain ellipse to equal radiuses, then client which attempts to set different values would receive an error.

Otherwise, if we say that ellipse is just a less constrained circle, we get a more subtle mistake. Suppose that shapes may not breach boundaries of the screen. Now suppose that a circle is replaced with an ellipse. Depending on which coordinate was tested, the shape might break out of the screen area without changing the client code. That is the exact violation of LSP.

Conclusion is - circle and ellipse are separate classes; 3DImage and ImageSet are separate classes.




回答2:


May be it's just me, but whenever I hear "derive or not derive" my first reaction "not derive" :)

Two reasons in this case:

  1. LSP is violated exactly because of those "small restrictions". So until you have AddImage in your base class which allows to add an image with any orientation, 3DImage is not an ImagesSet. There will be no way for algorithms to state that they need this feature (and comments is not a good place :) ), so you'll have to rely on run-time checks. It's still possible to program in this way, but this will be one more overhead for developers.

  2. Whenever you create some abstraction, it's important to understand why exactly it's created. With derivation you implicitly create an abstraction - it's interface of 3DImage. And instead of this it's better to create this abstraction explicitly. Create an interface class, list there methods useful for algorithms able to work on both data structures and make both ImagesSet and 3DImage implementing that interface possibly adding some other methods.

P.S. And likely AddImage will become one of those added methods - different in ImagesSet and 3DImage, but that depends...




回答3:


Dear maxim1000 and sysexpand,

Thanks for the answers. I agree with you. It is clear now that LSP is violated and in this case I can't derive 3DImage from ImagesSet.

I need to redesign the solution in the following way:

2DImage will contain:

  • 2DDimension's
  • PixelSize(in mm)
  • PixelData

2DImageOrientated will be derived from 2DImage and will contain new data:

  • 3DPoint origin,
  • 3DVector x-,y-axes

I will create pure interface IImagesSet:

  • number GetNumberOfImages()
  • RemoveImage(ImageIndex)
  • 2DImageOrientated Get2DImage()

ImagesSet will be derived from IImagesSet and will contain the following:

  • vector<2DImageOrientated>
  • Add2DImage(2DImageOrientated)
  • number GetNumberOfImages()
  • RemoveImage(ImageIndex)
  • 2DImageOrientated Get2DImage()

3DImage will be also derived from IImagesSet and will contain the following.

  • vector<2DImageOrientated>
  • Add2DImage(2DImage)
  • SetOrigin(3DPoint)
  • SetXAxis(3DVector)
  • SetYAxis(3DVector)
  • number GetNumberOfImages()
  • RemoveImage(ImageIndex)
  • 2DImageOrientated Get2DImage()

In this case I think LSP is not violated.



来源:https://stackoverflow.com/questions/25973235/can-i-apply-here-liskov-substitution-principle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!