Классы фабрики не обязательно должны ограничиваться одними только методами для создания объектов. В них можно помещать и другие методы, если это оправдывается моделью фабрики, например методы поиска, которые ищут в фабрике объекты и возвращают их, и методы для удаления объектов из фабрики. Реализация таких методов зависит от проекта и от решения проектировщика. Теперь обратим наше внимание на принципы инкапсуляции и сокрытия информации.
Инкапсуляция
Когда вы принимаете средство от головной боли, то, вероятно, не знаете, что оно содержит. Вас интересует только, снимет ли оно головную боль. В той же мере это относится к использованию программистами объектов, которые они получают. Когда мы начали использовать свой объект Саг, нам ничего не было известно о передаче, системе выпуска выхлопных газов или двигателе машины. Все, что нам требовалось, - это повернуть ключ и завести машину. Такая же задача должна ставиться при проектировании объектов.
Заключите все сложные данные и логику внутрь объекта и обеспечьте пользователей только существенными сервисами, которые нужны для взаимодействия с этим объектом. При этом фактически обеспечивается инкапсуляция сложных данных и деталей логики внутри объекта. Если сделать это надлежащим образом, то можно достичь выгоды от сокрытия информации, которая сейчас будет проиллюстрирована.
Как уже отмечалось, важно, чтобы пользователям класса ничего не было известно о членах-данных, которые в нем содержатся.
Хотя в РНР вполне допустимо в любой момент изменять члены созданного объекта, такие действия считаются плохой практикой программирования.
Вот пример, иллюстрирующий катастрофические события, которые могут случиться, если модифицировать члены объекта в обход его интерфейса. Предположим, что существует метод, устанавливающий скорость автомобиля, с именем который приводит к ошибке, если попытаться установить скорость выше 200 км/ч или меньше 0 км/ч. Допустим также, что конструктор не инициализирует двигатель и ключ, необходимый для запуска автомобиля:
$myKey = new^Sey.C'Kejii of my Porsche');
$car = new Car(); $car->engine = new Engine();
$car->speed = 400; $car->start($myKey);
$car->engine = 0; $car->stop();
В этом коде много ошибок, связанных с невозможностью интерпретирования или, что еще хуже, с тем, что код будет работать, но действовать неправильно. В первых трех строках не будет установлен член $requiredKey объекта потому что это не сделал наш конструктор.