без каких-либо изменений в реализации в граф.

зято из Эффективной Явы Джошуа Блох-

Пункт 14 (или пункт 16 в третьем издании): в открытых классах используйте методы доступа, а не открытые поля

// Подобные классы не должны быть публичными!

class Point {
  public double x;
  public double y;
}

Поскольку доступ к полям данных таких классов осуществляется напрямую, эти классы не предоставляют преимуществ инкапсуляции (элемент 13).

Вы не можете изменить представление без изменения API

Что автор подразумевает под последним предложением? Это утверждение используется много раз в одном и том же пункте. Пожалуйста, предложите.

Термин экспортируемый API или API следует интерпретировать в соответствии с предложением автора в книге

Экспортируемый API состоит из элементов API, которые доступны за пределами пакета, который определяет API.

 cricket_00725 сент. 2017 г., 15:19
@Xtreme Ну, OP только цитировал половину этого раздела книги :)
 XtremeBaumer25 сент. 2017 г., 15:15
опубликованный вами класс не является общедоступным. его пакет-приват. в целом твой вопрос не очень понятен

Ответы на вопрос(6)

что вы не можете изменить способ хранения данных и принять решение о том, как данные представлены, например, какой тип контейнера вы используете, без изменения API. Например, если вы решите, что хотите использовать точечный класс, а не двойной, для представленияx а такжеy, вам нужно будет изменить всех потребителей вашего класса (изменив API вашего класса).

Элементы данных являются частью представления (или реализации).

Поэтому, если вы сделаете элементы данных общедоступными, изменение представления также изменит API.

Например, если вы используете общедоступные методы получения вместо открытых элементов данных, вы можете изменить представление, не изменяя API.

Например, вот два разных представления с одним и тем же API:

class Point {
    private double x;
    private double y;

    public double getX () {return this.x;}
    public double getY () {return this.y;}
}

class Point {
    private InnerPoint p;

    public double getX () {return p.x;}
    public double getY () {return p.y;}
}

Это возможно только потому, что члены данных являются частными (и, следовательно, не являются частью API).

что когда у вас есть открытые поля, ваши поля (ваше представление) являются самим API, а когда вы меняете поля, меняется и API.

Если бы вы были публичными получателями для приватных полей, вы могли бы свободно играть с вашими приватными полями, и ваш API (ваши публичные методы) мог бы остаться таким же, как они.

В контексте означает, что однажды поделился, если вы склонны изменить атрибуты класса, определенного как таковой. Это невозможно без изменения существующего определения API. Например :-

class Point {
  public double x;
  public double y;

  // accessors
  double getX() { return this.x; }
  double getY() { return this.y; }
}

class Graph {

   void draw(Point point) {
       double x = point.x; // what if you decide this should be 0 if y is not 0?
}

Вместо этого, если бы вы использовалиgetX() Получив это, вы могли бы поместить эту логику в класс Point как

double getX() {
    if(p == 0) return 0;
    return this.x
}

без каких-либо изменений в реализации в граф.

Решение Вопроса

Ну, это довольно просто, предполагая класс Point.

class Point {
  public double x;
  public double y;
}

Теперь, по существу, x и y представляют точку в 2d плоскости. Если кто-то решит использовать его, он будет выглядеть следующим образом, например:

Point p;
p.x = 5;
p.y = 10;

Поскольку x и y объявлены общедоступными, они доступны всем, поэтому, если однажды вы решите переключить представление точек на радиус и угол на плоскости 2D, например,

class Point {
  public double r;
  public double angle;
}

Код из вышеперечисленного также должен быть изменен, а это означает, что клиенты, использующие ваш объект Point, должны будут заново скомпилировать свой код. Следовательно, объявив x и y общедоступными, вы ограничили себя тем, что эти объявления теперь являются частью API Point.

Однако лучшим подходом будет инкапсуляция внутреннего представления точки в состояние частной точки и предоставление только необходимых функций:

class Point {
  private double x;
  private double y;

  // Computes norm2 of the point
  public double norm2() {
    return Math.sqrt(x*x + y*y);
  }
}

Теперь тот, кто использует ваш класс Point, сможет использовать только общедоступные API в этом случае.norm метод, похожий на этот:

Point p;
// Init coordinates
double norm = p.norm();

Наконец, если вы хотите изменить внутреннее представление, ваш клиентский код не будет затронут вашим изменением в отличие от предыдущего примера.

 Shirgill Farhan25 сент. 2017 г., 15:40
Upvoted. Но класс - пакетный. Если я распространю API, он будет доступен не всем. Пожалуйста, предложите.
 Artem Barger25 сент. 2017 г., 16:16
Что ж, даже если класс является областью видимости канала и его внутреннее представление не просочится наружу, все равно это навязывает тесную связь вашего кода в одном пакете, что затрудняет его повторное использование и рефакторинг. Следовательно, мои предложения выше остаются неизменными независимо от того, является ли класс общедоступным или ограничен в объеме

private обеспечить инкапсуляцию.

Код с использованием этого API написан с использованиемpoint.x скорее, чемpoint.getX()

Ваш ответ на вопрос