немного с другой стороны зайду я ( со стороны проектирования по модели или Domain Driven Desing ) DDD
Какие типы объектов есть вообще?
Mutable Immutable State то есть изменяемые, неизменяемые и объекты с состоянием ( конкретно эти типы тут и рассмотрим )
Первый тип изменяемый ( тот который на протяжении работы программы может меняться как угодно ) то есть
$obj = new AnyClass();
$obj->prop = 123;
-----
$obj->prop = $_POST['prop']
и тд сколько угодно раз
Неизменяемые объекты или Value объекты
$obj = new Currency('RUR');
echo $obj;
или
$sex = new Sex('Male');
echo $sex;
и наконец объекты состояние
$var = new Car('Nissan', 100 , 0 );
echo $var->getState();
$var->addPassenger(new Human('ed', new Sex('male'));
$var->run();
echo $var->getState();
echo $var->getSpeed();
echo $var->addPassenger(new Human('Alice', new Sex('Female'));
теперь это рассмотрим что к чему на 3ем примере где я собрал все воедино
Итак
Human это изменяемый объект в нашем случае потому что со стороны бюрократии и хирургии Ed может стать Alice и наоборот были бы деньги и желание
Но вот сам пол в нашем случае уже неизменяемый объект, как в случае и пример 2 с валютой потому что нам не нужно менять значение валюты да и смысла нет в этом, если нам нужно будет поменять валюту у товара то мы делаем setCurrency(new Currency('EUR'));
и наконец сама машина по сути некоторые свойства изменяемые, а некоторые нет, причем некоторые меняются сами в зависимости от состояние и некоторые изменяются только на определенных состояниях ( например пассажира добавить только когда стоит, в процессе пути ни убрать не добавить не сможем )
для чего это надо тут геттер и сеттер
для меня тру языком ООП является ObjectiveC поэтому накладывать буду на него и брать примеры
и так для чего может понадобиться сеттер
например преобразовать в правильный формат данные если оно будет нужно, например
class Entry{
protected $id;
protected $createdAt;
function __construnct(){
$this->createdAt = new \DateTime();
}
public function setCreatedAt($createdAt){
if(!($createdAt instanceOf \DateTime)){
$createdAt = new \DateTime($createdAt);
}
$this->createdAt = $createdAt;
return $this;
}
}
Иногда одна модель используется с разным типом хранилища в некоторых случаях для даты вернется объект в некоторых строка, если несколько источников данных то следить за типом лучше внутри и тогда добавляя данные мы можем их попытаться преобразовать к DateTime либо уже получим исключение что строка не является датой
Тут скорее подействует принцип Kiss и Dry чем плодить проверки в каждом хранилище мы это перенесем в этот объект
Бывает бизнес процессы требуют хранить и получать данные как в Api сторонних сервисов, так и в СУРБД или еще NoSQL, например если у вас какой-то сервис по обработке и аггрегации данных с возможностью уведомления ( количество сервисов для сбора данных будет расти, а модель одна )
Dry в действии, а так же замена на публичное грозит тем что либо куча проверок при вставке либо куча преобразований при получении
-------------
Теперь рассмотрим вариант Immutable данных в ObjC это readonly свойства , средствами PHP указать конкретному свойству что оно только для чтения нельзя, для этого приходят геттеры и сеттеры и еще магия
у нас есть массив с readOnly полями которые задаются при создании объекта и потом только для чтения и при попытке изменить получаем Исключение, в случае с публичными мы не можем контролировать изменения что в некоторых случаях может привести к ошибке ( например транзакция на оплату товара в сторонний сервис ) и что бы горе программист который будет работать с вами не изменил данные случайно и потом магазин не продал товар стоимостью 100 USD за 100 RUR
-------------
Прошу прощения если описал слишком не связно и сумбурно, если будут вопросы задавайте ( утро понедельника оно такое для меня )