2014-09-22 6 views
2

У меня есть две моделей данных, которые представлены следующие классы:Могу ли я применить здесь Лиск принцип замещения

1) ImagesSet - это объект, который владеет 2DImage «S, каждый 2DImage имеет свой собственный позиция (начало координат (3DPoint), x-, y-оси (3DVector) и размерность по осям x и y (в пикселях)), но тот же размер пикселя (например, в мм), угол между x и y оси (90 градусов)

Этот объект имеет следующие методы (в псевдокоде):

  • AddImage (2DImage);
  • RemoveImage (ImageIndex);
  • номер GetNumberOfImages();
  • 2DImage Get2DImage (ImageIndex);

2) 3Dimage - An объекты, который похож на первый, но со следующими ограничениями: он может хранить изображения 2D только с той же Х-, у-оси и размеры вдоль осей х и у.

Правильно ли в данном случае для получения 3Dimage из ImagesSet? С моей точки зрения 3DImage «есть» ImagesSet (но с малыми ограничениями) Могу ли я применить здесь принцип замещения Лискова?

В этом случае, если мы пытаемся добавить изображение с помощью другого x, то оси y - метод AddImage либо генерирует исключение, либо возвращает ошибку.

Спасибо заранее, Сергей

ответ

4

Я согласен с maxim1000, что LSP будет нарушено, поскольку производный класс добавляет ограничения, которые не присутствуют в базовом классе , Если вы внимательно посмотрите на свое описание, вы заметите, что вопрос можно перевернуть в обратном порядке: может ли ImageSet выводиться из 3DImage?

Ваша ситуация несколько схожа с проблемой эллипса-круга. Какой из них происходит от другого? Является ли окружность эллипсом с ограничением, или является эллипсом окружности с дополнительным радиусом? Дело в том, что оба они ошибаются. Если вы ограничиваете эллипс равными радиусами, тогда клиент, который пытается установить разные значения, получит ошибку.

В противном случае, если мы говорим, что эллипс - это всего лишь ограниченный круг, мы получаем более тонкую ошибку. Предположим, что формы могут не нарушать границ экрана. Теперь предположим, что круг заменен эллипсом. В зависимости от того, какая координата была проверена, форма может вырваться из области экрана без изменения кода клиента. Это точное нарушение LSP.

Заключение - круг и эллипс являются отдельными классами; 3DImage и ImageSet - это отдельные классы.

+1

BTW, эта проблема возникает только для изменяемого интерфейса Circle и Ellipse. Если у нас есть только методы чтения в их интерфейсах, это нормально, чтобы получить круг из эллипса (если это полезно). – maxim1000

4

Может быть, это только мне, но всякий раз, когда я слышу «выводить или не выводить» моя первая реакция «не вытекает» :)

две причины в этом случае:

  1. LSP нарушается именно из-за этих «небольших ограничений». Итак, пока у вас нет AddImage в вашем базовом классе, что позволяет добавлять изображения с любой ориентацией, 3DImage is не a ImagesSet. Алгоритмы не смогут утверждать, что им нужна эта функция (и комментарии не являются хорошим местом :)), поэтому вам придется полагаться на проверки во время выполнения. По-прежнему можно программировать таким образом, но это будет еще один накладной для разработчиков.

  2. Всякий раз, когда вы создаете абстракцию, важно понять, почему именно она создана. С деривацией вы неявно создаете абстракцию - это интерфейс 3DImage. И вместо этого лучше создать эту абстракцию явно. Создайте класс интерфейса, перечислите там методы, полезные для алгоритмов, способных работать в обеих структурах данных, и сделайте как ImagesSet, так и 3DImage, реализуя этот интерфейс, возможно, добавив некоторые другие методы.

P.S. И вероятно AddImage станет одним из тех добавленных методов - разные в ImagesSet и 3DImage, но это зависит ...

0

Уважаемый maxim1000 и sysexpand,

Спасибо за ответы. Я с тобой согласен. Теперь ясно, что LSP нарушен, и в этом случае я не могу получить 3DImage от ImagesSet.

мне нужно переделать решение следующим образом:

2DImage будет содержать:

  • 2DDimension «ы
  • PixelSize (в мм)
  • PixelData

2DImageOrientated будут выведены из 2DImage и будет содержать новые данные:

  • 3DPoint происхождение,
  • 3DVector x-, у-оси

Я создам чистый интерфейс IImagesSet:

  • номер GetNumberOfImages()
  • RemoveImage (ImageIndex)
  • 2DImageOrientated Get2DImage()

ImagesSet будут выведены из IImagesSet и будет содержать следующие:

  • вектор < 2DImageOrientated>
  • Add2DImage (2DImageOrientated)
  • номер GetNumberOfImages()
  • RemoveImage (ImageIndex)
  • 2DImageOrientated Get2DImage()

3DImage также будет получен из IImagesSet и будет содержать следующее.

  • вектор < 2DImageOrientated>
  • Add2DImage (2DImage)
  • SetOrigin (3DPoint)
  • SetXAxis (3DVector)
  • SetYAxis (3DVector)
  • номер GetNumberOfImages()
  • RemoveImage (ImageIndex)
  • 2DImageOrientated Get2DImage()

В этом случае я думаю, что LSP не нарушается.