Главная » Java, Советы » 3аменяйте структуру классом

0

 

Конструкция struct языка С не была принята в языке программирования Java потому, что класс выполняет все то же самое, что может делать структура, и даже более того. Структура группирует несколько полей данных в один общий объект, тогда как класс связывает с полученным объектом операции, а также позволяет скрывать поля данных от пользователей объекта. Иными словами, класс может инкапсулировать

 

encapsulate) свои данные в объекте, доступ к которому осуществляется только через его методы. Тем самым у разработчика появляется возможность менять внутреннее представление объекта (статья 12).

После первого знакомства с языком Java некоторые программисты, ранее пользовавшиеся языком С, приходят к заключению, что в некоторых случаях класс слишком тяжеловесен, чтобы заменить структуру, однако это не так. Вырожденный класс, состоящий исключительно из полей данных, примерно равнозначен структуре из языка С:

 

// Вырожденные классы, подобные этому,

// не должны быть открытыми!

class Point {

public float х;

public float у;

}

 

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

 

// Класс с инкапсулированной структурой

class Point {

private float х;

private float у;

public Point(float х, float у) {

       this. х = х;

this.y = у;

}

public float getX() { return х; }

public float getY() { return у; }

public void setX(float х) { this.x = х; }

public void setY(float у) { this.y = у; }

}

 

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

 

 

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

Несколько классов в библиотеках для платформы Java нарушают совет, касающийся запрещения непосредственного доступа к полям открытого класса. В частности, это классы Point и Dimension из пакета java.awt. Не следует подражать этим классам, лучше рассматривать их как предупреждение. В статье 37 показано, как раскрытие внутреннего содержания класса Dimension привело к серьезным проблемам с производительностью, которые нельзя было разрешить, не затрагивая клиентов.

Источник: Джошуа Блох, Java TM Эффективное программирование, Издательство «Лори»

По теме:

  • Комментарии