Объектно-ориентированный программист недовольно поморщится и пожалуется на процедурную природу реализации — и будет прав. Но возможно, его презрительная усмешка не обоснована. Подумайте, что произойдет при включении в Geometry функции perimeter(). Классы фигур остаются неизменными! И все остальные классы, зависящие от них, тоже остаются неизменными! С другой стороны, при добавлении новой разновидности фигур мне придется изменять все функции Geometry, чтобы они могли работать с ней. Перечитайте еще раз. Обратите внимание на то, что эти два условия диаметрально противоположны.
Теперь рассмотрим объектно-ориентированное решение из листинга 6.6. Метод area() является полиморфным, класс Geometry становится лишним. Добавление новой фигуры не затрагивает ни одну из существующих
Polymorphic Shapes
public class Square implements Shape {
private Point topLeft;
private double side;
public double area() {
return side*side;
}
}
public class Rectangle implements Shape {
private Point topLeft;
private double height;
private double width;
public double area() {
return height * width;
}
}
public class Circle implements Shape {
private Point center;
private double radius;
public final double PI = 3.141592653589793;
public double area() {
return PI * radius * radius;
}
}
И снова мы наблюдаем взаимодополняющую природу этих двух определений. В этом проявляется основополагающая дихотомия между объектами и структурами данных.
Обратные утверждения также истинны.
Таким образом, то, что сложно в ОО, просто в процедурном программировании, а то, что сложно в процедурном программировании, просто в ОО!
В любой сложной системе возникают ситуации, когда вместо новых функций в систему требуется включить новые типы данных. Для таких ситуаций объекты и объектно-ориентированное программирование особенно уместны. Впрочем, бывает и обратное — вместо новых типов данных требуется добавить новые функции. Тогда лучше подходит процедурный код и структуры данных.
Опытные программисты хорошо знают: представление о том, что все данные должны представляться в виде объектов —
Закон Деметры
Хорошо известное эвристическое правило, называемое
В более точной формулировке закон Деметры гласит, что метод
• объекты, созданные
• объекты, переданные
• объекты, хранящиеся в переменной экземпляра
Метод
Следующий код нарушает закон Деметры (среди прочего), потому что он вызывает функцию getScratchDir() для возвращаемого значения getOptions(), а затем вызывает getAbsolutePath() для возвращаемого значения getScratchDir().
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
Крушение поезда