A бетонная фабрика - это класс, который реализует абстрактную фабрику и может быть создан. Абстрактная фабрика - это неинстанцируемый класс, который определяет интерфейс фабрики. Например (используя Java для иллюстрации), абстрактная фабрика (FooFactory
) будет выглядеть примерно так:
public class Foo {}
public interface FooFactory {
public Foo createFoo() { /* ... */ }
}
Поскольку этот FooFactory
является интерфейсом (является абстрактным), он не может быть создан. Например, следующее будет недопустимым (и не может быть скомпилировано):
FooFactory factory = new FooFactory();
Конкретная фабрика (в данном случае называемая ConcreteFooFactory
) является инстанцируемым классом, который реализует интерфейс FooFactory
:
public class ConcreteFooFactory implements FooFactory {
@Override
public Foo createFoo() { /* ... */ }
}
FooFactory factory = new ConcreteFooFactory();
Все это вызывает вопрос: зачем создавать абстрактную фабрику, а затем бетонную фабрику? Причина в том, что абстрактная фабрика определяет интерфейс (методы, которые могут быть вызваны) фабрики, но не определяет какого-либо конкретного поведения фабрики. Это позволяет нам создавать несколько реализаций FooFactory
(конкретные классы), каждая из которых имеет свое специфическое поведение. клиенты , зависящие от фабрики, могут зависеть от абстрактной фабрики, а ее поведение может меняться в зависимости от того, какая конкретная фабрика ему передана:
public class BlueFooFactory implements FooFactory {
@Override
public Foo createFoo() { /* ...create blue Foo... */ }
}
public class RedFooFactory implements FooFactory {
@Override
public Foo createFoo() { /* ...create red Foo... */ }
}
public class FooClient {
private FooFactory factory;
public FooClient(FooFactory factory) {
this.factory = factory;
}
public void doSomething() {
Foo someFoo = factory.createFoo();
// ...do something with someFoo...
}
}
// Option 1
FooClient client = new FooClient(new BlueFooFactory());
// Option 2
FooClient client = new FooClient(new RedFooFactory());
Хотя эти примеры сделаны на Java, они могут быть выполнены и на Javascript. См. Объектно-ориентированный JavaScript: глубокое погружение в классы ES6 для получения дополнительной информации.