Страницы

Поиск по вопросам

пятница, 20 марта 2020 г.

Целесообразность фабричного метода

#c_sharp #net


Допустим, есть некоторая иерархия классов, где каждый последующий класс наследуется
от предыдущего.

Мне хотелось бы, что бы каждый класс имел свой статический метод Parse, который бы
принимал строку и возвращал построенный объект.

Как я понимаю, переопределить статический метод в классах потомках нельзя, а можно
только через перекрытие с и спользованием new...

Так вот, вот вопрос в том, правильно ли это делать через статический метод или есть
какой-то другой вариант?
    


Ответы

Ответ 1



Попробую ответить, отталкиваясь от термина Фабричный метод, который вы использовали. Предположим, что у вас есть некая сложная иерархия: interface IType; class Type : IType; class SecondType : Type; class ThirdType : IType; Вы ходите иметь возможность делегировать инстанцирование объекта, пользуясь всеми преимуществами полиморфизма, чтобы создать что-то вроде такого класса: class TypeProcessor where T : IType { public void Process(string input) { var someObject = T.Parse(input); Console.WriteLine(this.ProcessInternal(someObject)); } protected string virtual ProcessInternal(T value) { return value.ToString(); } } Такой код не будет работать, потому что static методы не наследуются, да и для такого не предназначены. Зато мы можем сделать прямо так, как предполагалось в этом шаблоне проектирования изначально, а именно - создать абстрактную фабрику (или интерфейс фабрики) и фабрики-наследников для конкретных типов: interface ITypeFactory where T : IType { T Parse(string input); } class TypeFactory : ITypeFactory where T : IType { public virtual Type Parse(string input) { ... } } class SecondTypeFactory : TypeFactory { public override Type Parse(string input) { ... } } class ThirdTypeFactory : ITypeFactory { public ThirdType Parse(string input) { ... } } Соответственно в нашем классе TypeProcessor произойдут изменения: class TypeProcessor where T : IType { private readonly ITypeFactory factory; TypeProcessor(ITypeFactory factory) { this.factory = factory; } public void Process(string input) { var someObject = this.factory.Parse(input); Console.WriteLine(this.ProcessInternal(someObject)); } protected string virtual ProcessInternal(T value) { return value.ToString(); } } Собственно, об этом и говорит паттерн Фабричный метод (можно посмотреть картинку на wiki). Есть Creator для общего типа и ConcreteCreator, который создает объекты конкретного типа. В дополнение приведу статью, где автор рассуждает на тему использования статики в C#.

Комментариев нет:

Отправить комментарий