Шаблоны проектирования JavaScript: что такое бетонная фабрика? - PullRequest
1 голос
/ 15 мая 2019

Читая о фабриках в этой статье , я столкнулся с этими двумя терминами AbstractFactory и ConcreteFactory .

enter image description here

Во время чтения StackOverflow я нашел несколько хороших ответов (например, этот вопрос SO ), в которых говорится о фабриках и абстрактных фабриках, но все еще не ясно, что такое конкретная фабрика.

Итак, я хотел спросить:

  1. Что такое бетонный завод?
  2. Чем он отличается от абстрактной фабрики?

РЕДАКТИРОВАТЬ: Задав вопрос № 2 в отдельном вопросе ( Абстрактная фабрика против бетонной фабрики ), чтобы разделить эти две дискуссии.


Мое понимание (о фабриках):

  • На высоком уровне я понимаю, что под фабрикой мы ссылаемся на метод, который возвращает совершенно новое что-то (может быть что угодно, объект, метод, все, что нужно как наше требование), что мы бы назвали фабрикой. Вот, пожалуйста, поправьте меня, если я ошибаюсь.
  • Фабрики инкапсулируют и отделяют создание объектов от остальной части вашего кода. Ниже приведен пример, иллюстрирующий то же самое:

// This function is a factory. When called, creates and returns a new object every time
function ourFactoryFn (firstName, lastName) {
    var a = {
        prop1:  firstName,
        prop2: lastName,
        prop3: firstName + ' ' + lastName + ' says Hello world!'
    }
    return a;
};

// Now, let's use our factory to produce new objects
// let's actually have an example to treat it like real life factories :P
var inputArr = [
    {firstName: 'Barack', lastName: 'Obama'},
    {firstName: 'Narendra', lastName: 'Modi'},
    {firstName: 'Mike', lastName: 'Tyson'},
    {firstName: 'Mahatma', lastName: 'Gandhi'},
    {firstName: 'Donald', lastName: 'Trump'},
    {firstName: 'Priyanka', lastName: 'Chopra'}
];
var outputArr = [];
inputArr.forEach(function (x) {
    var newObj = ourFactoryFn(x.firstName, x.lastName); // we used our factory
    console.dir(newObj); // print the freshly created object
    outputArr.push(newObj);
});

1 Ответ

1 голос
/ 15 мая 2019

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 для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...