Понятие «Инкапсуляция» означает, что вся информация, которая нужна для работы конкретного объекта, должна храниться внутри этого объекта. Если нужно вносить изменения, методы для этого тоже должны лежать в самом объекте — посторонние объекты и классы этого делать не могут. Для внешних объектов доступны только публичные атрибуты (свойства) и методы.
Одним из самых важных факторов при проектировании компонентов приложения является сокрытие внутренних данных компонента и деталей его реализации от других компонентов приложения и предоставление набора методов для взаимодействия с ним (API). Этот принцип является одним из четырёх фундаментальных принципов ООП и называется инкапсуляцией.
Например, метод для внесения данных в карточку товара должен обязательно быть прописан в классе «Карточка товара». А не в классе «Корзина» или «Каталог товаров».
Такой принцип обеспечивает безопасность и не даёт повредить данные внутри какого-то класса со стороны. Ещё он помогает избежать случайных зависимостей, когда из-за изменения одного объекта что-то ломается в другом.
Правильная инкапсуляция важна по многим причинам:
1. Она способствует переиспользованию компонентов: поскольку в этом случае компоненты взаимодействуют друг с другом только посредством их API и безразличны к изменениям внутренней структуры, они могут использоваться в более широком контексте.
2. Инкапсуляция ускоряет процесс разработки: слабо связанные друг с другом компоненты (то есть компоненты, чей код как можно меньше обращается или использует код других компонентов) могут разрабатываться, тестироваться и дополняться независимо.
3. Правильно инкапсулированные компоненты более легки для понимания и процесса отладки, что упрощает поддержку приложения.
Например, в языке PHP инкапсуляция реализована с помощью модификаторов доступа, которыми можно пометить его свойство или метод.
В PHP всего 3 модификатора доступа:
- public – полный доступ к сущности (полю или методу класса) из любого пакета;
- protected – доступ к сущности только для классов своего пакета и наследников класса;
- private – доступ только внутри класса, в котором объявлена сущность.
Для достижения правильной инкапсуляции также необходимо предоставить корректный API для работы с компонентом.
Пример правильной инкапсуляции:
class User
{
// Мы скрыли от других эти свойства
private $firstName;
private $lastName;
public function __construct($firstName, $lastName)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
}
// Мы разрешаем менять инициалы пользователя через метод,
// а не через правку свойств $firstName, $lastName
public function setUserInitials($firstName, $lastName)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
}
// Мы скрыли от других показ инициалов
private function getUserInitials(): string
{
return 'Mr. ' . $this->firstName . ' ' . $this->lastName;
}
// Мы разрешаем показать информацию о пользователе
public function printUserInfo(): string
{
return $this->getUserInitials();
}
}
Итого: Инкапсуляция — это скрытие внутреннего состояния и функций объекта и предоставление доступа только через открытый набор функций.