@carcw

Как правильно использовать паттерн проектирования стратегия?

Я пытаюсь применить паттерн "Стратегия", но возникают 2 момента в которых не уверен как делать правильно.

У меня есть класс FormBuilder (использует для построения формы), который использует одну из доступных стратегий для построения формы. Стратегия определяется исходя из входных параметров, которые передаются в FormBuilder.

Возникает 2 вопроса:
  1. Правильно ли осуществлять выбор стратегии внутри класса FormBuilder, или выбор стратегии и установка должна производиться снаружи?
  2. Не нарушает ли код в примере ниже принцип "Закрыт для модификации, открыт для расширения"? Если мне потребуется добавить новую стратегию или удалить существующую, мне также всегда придется редактировать класс FormBuilder.


class Form {
    // Данные формы
}

interface IFormStrategy {
    execute(params: object): Form;
}

class SimpleFormStrategy implements IFormStrategy {
    public execute(params: object): Form {
        // Здесь должна быть логика построения простой формы
        return new Form();
    }
}

class ExtendedFormStrategy implements IFormStrategy {
    public execute(params: object): Form {
        // Здесь должна быть логика построения расширенной формы
        return new Form();
    }
}

class CustomFormStrategy implements IFormStrategy {
    public execute(params: object): Form {
        // Здесь должна быть логика построения кастомной формы
        return new Form();
    }
}

class FormBuilder {
    public build(params: object): Form {
        let strategy: IFormStrategy;

        // В этом месте осуществляется выбор стратегии исходя из параметра params

        // Если должна быть простая форма
        strategy = new SimpleFormStrategy();
        // Если должна быть расширенная форма
        strategy = new ExtendedFormStrategy();
        // Если должна быть кастомная форма
        strategy = new CustomFormStrategy();

        return strategy.execute(params);
    }
}
  • Вопрос задан
  • 153 просмотра
Пригласить эксперта
Ответы на вопрос 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
Если не хотите просто передавать сам класс стратегии как параметр, то остаётся только сделать жэшмапу где ключём будет имя параметра, а значением собсно класс стратегии. При добавлении новой стратегии - добавляеете её же в мапу. Условно как-то так:
class FormBuilder {
    public static strategies: { [key: string]: {new(): IFormStrategy} } = {
        simple: SimpleFormStrategy,
        extended: ExtendedFormStrategy,
    };
    public build(params: { strategy: string }): Form {
        let strategy: IFormStrategy = new FormBuilder.strategies[params.strategy]();
        return strategy.execute(params);
    }
}

FormBuilder.strategies.custom = CustomFormStrategy;

const formBuilder = new FormBuilder();
formBuilder.build({ strategy: 'custosm' });

Естесно мапу можно сделать приватной и добавление осуществлять публичным методом. Или хранить вообще отдельно. Нужны также проверки что такая стратегия вообще есть, но это всё уже детали...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы