Страницы

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

суббота, 11 января 2020 г.

Что использовать абстрактный класс или интерфейс в фабричном методе?

#c_sharp #ооп #шаблоны_проектирования


Полностью осознаю, что это очередной вопрос из  серии "Разница между абстрактным
классом и интерфейсом". И должен сказать, что для меня эти две концепции ясны или возможно
нет раз задаю этот вопрос :)

Наверное каждый второй, если не первый из девелоперов использует порождающий паттерн
"Фабричный метод" и меня интересует вопрос, так какую абстракцию лучше использовать
при реализация этого паттерна: абстрактный класс или интерфейс?

Туториалы в сети тоже не едины в этом: кто-то рассказывает этот паттерн при помощи
абстрактного класса, а кто-то при помощи интерфесов. Хотя должен заметить, что большинство
статей касаемо фабричного метода ведут свои рассуждения на абстрактных классах.

Вот пример из википедии, который рассказывает паттерн на 

Абстрактных классах

namespace CSharpConsoleApp
{
    abstract class AbstractProduct
    {
        public abstract string GetType();
    }

    class ConcreteProductA : AbstractProduct
    {
        public override string GetType() { return "ConcreteProductA"; }
    }

    class ConcreteProductB : AbstractProduct
    {
        public override string GetType() { return "ConcreteProductB"; }
    }

    abstract class AbstractCreator
    {
        public abstract AbstractProduct FactoryMethod();
    }

    class ConcreteCreatorA : AbstractCreator
    {
        public override AbstractProduct FactoryMethod() { return new ConcreteProductA(); }
    }

    class ConcreteCreatorB : AbstractCreator
    {
        public override AbstractProduct FactoryMethod() { return new ConcreteProductB(); }
    }
    class Program
    {
        static void Main(string[] args)
        {
            AbstractCreator[] creators = { new ConcreteCreatorA(), new ConcreteCreatorB() };
            foreach (AbstractCreator creator in creators)
            {
                AbstractProduct product = creator.FactoryMethod();
                Console.WriteLine("Created {0}", product.GetType());
            }

            Console.Read();
        }
    }
}


а это переделанный мной вариант на

Интерфейсах

namespace CSharpConsoleApp
{
    interface IProduct
    {
        string GetType();
    }

    class ProductA : IProduct
    {
        public string GetType() { return "ProductA"; }
    }

    class ProductB : IProduct
    {
        public string GetType() { return "ProductB"; }
    }
    interface ICreatorProduct
    {
        IProduct FactoryMethod();
    }

    class CreatorProductA : ICreatorProduct
    {
        public IProduct FactoryMethod() { return new ProductA(); }
    }

    class CreatorProductB : ICreatorProduct
    {
        public IProduct FactoryMethod() { return new ProductB(); }
    }

    class Program
    {
        static void Main(string[] args)
        {           
            ICreatorProduct[] productCreators = { new CreatorProductA(), new CreatorProductB() };
            foreach (ICreatorProduct creatorProduct in productCreators)
            {
                IProduct product = creatorProduct.FactoryMethod();
                Console.WriteLine("Created {0}", product.GetType());
            }

            Console.Read();
        }
    }
}




Так какова лучшая практика использования данного паттерна в плане абстракций?
    


Ответы

Ответ 1



Смысл абстрактного класса — совместное использование кода классами-потомками. Абстрактный класс нужен для того, чтобы было легко создавать немного отличающиеся классы, общую часть которых вы выносите в реализованные методы абстрактного класса. В вашем случае абстрактный класс не нужен. В вашем коде смысл AbstractProduct состоит лишь в том, чтобы в дочернем классе затребовать наличия метода string GetType(). Точно так же смысл AbstractCreator лишь в том, чтобы в дочернем классе затребовать наличия метода AbstractProduct FactoryMethod(). Это прекрасно ложится на предназначение интерфейсов. Вывод: интерфейсы в данном коде намного более естественны. Предположу, что код, который использует абстрактные классы, написан для языка C++, в котором интерфейсов просто нет.

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

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