Задать вопрос
@RMate

Как правильно реализовать создание дочерних экземпляров класса?

Всем привет!
Имеется что-то вроде автоответчика, в скрипт могут поступать вопросы, допустим, с почты, по смс, из соцсети.
Задача алгоритма подобрать ответ, и ответить туда, откуда пришёл запрос.
Для чего был сделан интерфейс
IAnswerProvider, который требует всех реализующих его потомков реализовать метод sendAnswer()
Имеются наследующие его классы
SmsAnswerProvider
EmailAnswerProvider
PhoneAnswerProvider

И всё работает хорошо, пока не возникает самый интересный вопрос.
Я хочу отправить уведомление всем, кто когда-либо взаимодействовал со мной... для чего я выбираю из базы всех пользователей (в базе содержится информация о источнике) и начинаю рассылку.
в реализации я вынужден делать что-то вроде
switch(источник)
    case "sms": 
        answerProvider = new SmsAnswerProvider();
        answerProvider.sendAnswer("Hello world")!
        break;
    case "email": 
        answerProvider = new EmailAnswerProvider();
        answerProvider.sendAnswer("Hello world")!
        break;


А если источников будет 30? Я делаю что-то не так. Подскажите, пожалуйста, как правильно реализовать в данном случае мою идею. Спасибо.

PS:
Думал, что мне идеально подойдет паттерн "фабрика", но чем дальше я про него читаю, тем меньше понимаю, нужен ли он мне.
  • Вопрос задан
  • 167 просмотров
Подписаться 2 Простой 6 комментариев
Ответ пользователя Alex Wells К ответам на вопрос (3)
Alex_Wells
@Alex_Wells
PHP/Kotlin
Создаете Registry, где храните RegistryEntry. Для каждого типа провайдера по соответствующей реализации RegistryEntry.

pseudo:
class Registry<T extends RegistryEntry> {
    private Map<string, T> registries = new HashMap();

    public void register(T entry) {}
    public T find(string registryName) {}
}

class RegistryEntry {
    public string registryName;
}

class AnswerProviderRegistry<AnswerProviderRegistryEntry> extends Registry {}
class AnswerProviderRegistryEntry<T extends IAnswerProvider> extends RegistryEntry {
    abstract public T create();
}

class SmsAnswerProviderRegistryEntry<SmsAnswerProvider> extends AnswerProviderRegistryEntry {
    constructor() {
        this.registryName = "sms";
    }

    public SmsAnswerProvider create() {
        return new SmsAnswerProvider();
    }
}
Ответ написан