Чистый код. Создание, анализ и рефакторинг (Мартин) - страница 76

>    }

>  }


>  public int getLineCount() {

>    return lineCount;

>  }


>  public int getMaxLineWidth() {

>    return maxLineWidth;

>  }


>  public int getWidestLineNumber() {

>    return widestLineNumber;

>  }


>  public LineWidthHistogram getLineWidthHistogram() {

>    return lineWidthHistogram;

>  }


Листинг 5.6 (продолжение)

>  public double getMeanLineWidth() {

>    return (double)totalChars/lineCount;

>  }


>  public int getMedianLineWidth() {

>    Integer[] sortedWidths = getSortedWidths();

>    int cumulativeLineCount = 0;

>    for (int width : sortedWidths) {

>      cumulativeLineCount += lineCountForWidth(width);

>      if (cumulativeLineCount > lineCount/2)

>        return width;

>    }

>    throw new Error("Cannot get here");

>  }


>  private int lineCountForWidth(int width) {

>    return lineWidthHistogram.getLinesforWidth(width).size();

>  }


>  private Integer[] getSortedWidths() {

>    Set widths = lineWidthHistogram.getWidths();

>    Integer[] sortedWidths = (widths.toArray(new Integer[0]));

>    Arrays.sort(sortedWidths);

>    return sortedWidths;

>  }

>}

Глава 6. Объекты и структуры данных

Существует веская причина для ограничения доступа к переменным в программах: мы не хотим, чтобы другие программисты зависели от них. Мы хотим иметь возможность свободно менять тип или реализацию этих переменных так, как считаем нужным. Тогда почему же многие программисты автоматически включают в свои объекты методы чтения/записи, предоставляя доступ к приватным переменным так, словно они являются открытыми?

Абстракция данных

Давайте сравним между собой листинги 6.1 и 6.2. В обоих случаях код представляет точку на декартовой плоскости. Однако в одном случае реализация открыта, а в другом она полностью скрыта от внешнего пользователя.


Листинг 6.1. Конкретная реализация Point

>public class Point {

>  public double x;

>  public double y;

>}


Листинг 6.2. Абстрактная реализация Point

>public interface Point {

>  double getX();

>  double getY();

>  void setCartesian(double x, double y);

>  double getR();

>  double getTheta();

>  void setPolar(double r, double theta);

>}

Элегантность решения из листинга 6.2 заключается в том, что внешний пользователь не знает, какие координаты использованы в реализации — прямоугольные или полярные. А может, еще какие-нибудь! Тем не менее интерфейс безусловно напоминает структуру данных.

Однако он представляет нечто большее, чем обычную структуру данных. Его методы устанавливают политику доступа к данным. Пользователь может читать значения координат независимо друг от друга, но присваивание координат должно выполняться одновременно, в режиме атомарной операции.