Ответ
Да, это не только правильно, но и является фундаментальным принципом инкапсуляции в ООП. Прямой доступ к приватным свойствам нарушает инкапсуляцию, лишая класс контроля над своими данными.
Почему геттеры (и сеттеры) — это must-have в production-коде:
- Контроль над состоянием: Геттер позволяет возвращать не просто сырое значение, а вычисляемое или форматированное. Например, геттер для даты может возвращать ее в определенном часовом поясе.
- Ленивая инициализация (lazy load): Вы можете инициализировать тяжелый ресурс только при первом обращении через геттер.
- Совместимость и рефакторинг: Внутреннее представление данных можно полностью изменить, оставив публичный API (геттер) неизменным.
Практический пример с логикой в геттере:
class User {
private DateTimeImmutable $createdAt;
private ?string $firstName;
private ?string $lastName;
public function __construct(string $firstName, string $lastName) {
$this->createdAt = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$this->firstName = $firstName;
$this->lastName = $lastName;
}
// Геттер с вычисляемым значением
public function getFullName(): string {
return trim($this->firstName . ' ' . $this->lastName);
}
// Геттер с форматированием и инвариантом (всегда UTC)
public function getCreatedAtIso8601(): string {
return $this->createdAt->format(DateTimeInterface::ATOM); // Всегда в стандартном формате
}
// Геттер, который может вернуть null, но мы это явно указываем в типе
public function getLastName(): ?string {
return $this->lastName;
}
}
// Использование
$user = new User('John', 'Doe');
echo $user->getFullName(); // "John Doe"
echo $user->getCreatedAtIso8601(); // "2023-10-27T10:00:00+00:00"
// echo $user->createdAt; // Fatal error: Cannot access private property
Таким образом, геттер — это не просто обертка, а полноценный метод, который является частью контракта класса и может содержать важную логику.