Вопрос дизайна относительно фабричного образца - PullRequest
0 голосов
/ 01 марта 2019

Я хочу добавить тип IGameScoreSource в класс, но я не знаю, как это сделать.

static class GamesScoreSourceFactory
{
    public IGameScoreSource GetGameScoreSource(GameScoreSourceType gameScoreSourceType)
    {
        switch(gameScoreSourceType)
        {
            case FromFile:
                return new GameScoreFile();
            case FromDB:
                return new DatabaseRepos();
            case FromThirdPartyAPI:
                return new ThirdPartyWrapper();
        }   
    }
}

У меня есть два вопроса для двух разных сценариев.

Все три случая волшебным образом выясняют, где получить параметры.Поэтому для GameScoreFile он знает, какой путь к файлу искать, для DatabaseRepos он знает, где найти строку подключения.

Предположительно, эти места жестко заданы в конкретных классах.Но что если я захочу поменять месторасположение?Предполагая, что scores.txt было жестко запрограммировано в GameScoreFile.cs что, если бы вместо этого я хотел rand_scores.txt?

Итак:

 static class GamesScoreSourceFactory
    {
        public IGameScoreSource GetGameScoreSource(GameScoreSourceType gameScoreSourceType, string param)
        {
            switch(gameScoreSourceType)
            {
                case FromFile:
                    return new GameScoreFile(string param);
                case FromDB:
                    return new DatabaseRepos(string param);
                case FromThirdPartyAPI:
                    return new ThirdPartyWrapper(ThirdPartyConfig conf{IPAddress = ipAddress, Port = port});
            }   
        }
    }

Первые два случая были хорошими, нов третьем случае нет, потому что он принимает объект конфигурации.

Нужно ли создавать другой фабричный класс?Но разве вызывающему коду не нужно знать, какой объект Factory вызывать, и в результате он сам становится Factory?

Я не уверен, как с этим справиться ... Если это дубликат, пожалуйста, ссылкуя.

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Я бы попытался изолировать зависимости так, чтобы класс фабрики не должен был знать слишком много.

Допустим, что каждая из ваших конкретных реализаций IGameScoreSource имеет свои собственные зависимости.В приведенном выше примере двум требовалась строка, а третьему - ThirdPartyConfig.

Это выглядит не так много, как только вы продвигаетесь и реорганизуете свои классы каждый раз, когда вводите или изменяете зависимость, класс фабрикитакже должен измениться.Не идеально.

Вы можете создать фабрику для каждого конкретного типа, и тогда любое изменение в одной из реализаций повлияет только на его собственную фабрику.Основной класс фабрики будет работать только с этими конкретными фабриками и не будет зависеть от каждого изменения.

Правильное решение зависит от модели вашего домена и используемого вами подхода IOC.

0 голосов
/ 01 марта 2019

В идеале вы должны внедрить следующие типы как зависимость от фабричного класса

GameScoreFile
DatabaseRepos
ThirdPartyWrapper

Таким образом, какой бы фреймворк вы не использовали для разрешения зависимостей, он знает, что передать соответствующему типу.

...