Паттерн «абстрактная фабрика», в отличии от «шизофреника» паттерна «синглтон», вполне даже имеет аналогии в окружающем мире.

Главная цель: порождающий паттерн «абстрактная фабрика» служит для группового изменения поведения объектов, сохраняя при этом общий интерфейс.

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

Пример кода php класса pattern abstract factory

/* вот наша абстрактная фабрика */ abstract class zooFactory {
будем считать, что этот статический класс и метод - enterRoom::whatSee() - существует и независимо от всей группы дает объективную картину. На его месте в коде может быть метод указания на операционную систему или используемый язык, или т.п.
/* точка входа в наш паттерн */ public static function getFactory() { /* по нашему сценарию, вы вошли в комнату и увидели что-то */ if ( enterRoom::whatSee() == 'horse' ) { return( new horseFactory() ); } else { return( new tigerFactory() ); } } /* у наследованного класса должен быть метод создания рта */ public abstract function createMouth(); /* по идее мы еще затронули конечности, но опустим их */ // public abstract function createLegs(); }
/* класс лошадей */ class horseFactory extends zooFactory { /* обязательный метод создания рта */ public function createMouth() { return( new horseMouth() ); } }
/* класс тигров */ class tigerFactory extends zooFactory { /* обязательный метод создания рта */ public function createMouth() { return( new tigerMouth() ); } }
/* в группу классов входит интерфейс ртов */ abstract class zooMouth { /* у наследованного класса должен быть метод использования рта */ public abstract function useIt(); }
/* класс ртов лошади */ class horseMouth extends zooMouth { /* игогокаем */ public function useIt() { echo 'EEEHHGGOOGOOO'; } }
/* класс ртов тигра */ class tigerMouth extends zooMouth { /* рычим */ public function useIt() { echo 'HRRRRR'; } }
// создаем существо, то есть входим в фабрику $zooBeing = zooFactory::getFactory(); // создаем рот без понимания, что именно за существо $mouth = $zooBeing->createMouth(); // используем рот - первый звук детеныша - !независимо от того, кто это! $mouth->useIt();

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

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

Взаимодействие происходит лишь отталкиваясь от интерфейса по схеме:
родился() —> открыл рот() -> издал звук()

Надеюсь, стало понятно, как использовать данный паттерн «абстрактная фабрика» .

Удачного кода!