Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 09:15
Оценка:
Вот рассмотрим простейшую учебную:
есть бренды электроники.
для каждого бренда несколько девайсов (мобильник, планшет)
для простоты ограничим функционал включением.


static void Main(string[] args)
        {
            foreach (IDeviceFactory factory in GetDeviceFactories())
            {
                Client client = new Client(factory);
                WorkWithDevices(client);
            }
        }

        static IDeviceFactory[] GetDeviceFactories()
        {
            return new IDeviceFactory[] {
                new AppleDevicesFactory(),
                new SamsungDevicesFactory(),
                new XiaomiDevicesFactory()
            };
        }


class Client
    {
        private const int CableLength = 10;

        public ICellPhone CellPhone;
        public ICharger Charger;
        public ILaptop Laptop;
        public ITablet Tablet;

        public Client(IDeviceFactory factory)
        {
            CellPhone = factory.CreateCellPhone();
            Charger = factory.CreateCharger(CableLength);
            Laptop = factory.CreateLaptop();
            Tablet = factory.CreateTablet();
        }
    }

   public class AppleDevicesFactory : IDeviceFactory
    {
        public ICellPhone CreateCellPhone()
        {
            return new CellPhoneApple();
        }

        public ICharger CreateCharger(int cableLength)
        {
            return new ChargerApple(cableLength);
        }

        public ILaptop CreateLaptop()
        {
            return new LaptopApple();
        }

        public ITablet CreateTablet()
        {
            return new TabletApple();
        }
    }



Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?
Re: Абстрактная фабрика и дженерики
От: Sharov Россия  
Дата: 20.08.19 09:48
Оценка: 3 (2) -1
Здравствуйте, Kaifa, Вы писали:

Навскидку как-то так:

   public class AppleDevicesFactory : IDeviceFactory 
    {
        public T CreateInstance<T>() where T:new()
        {
            return new T();
        }

        public ICharger CreateCharger(int cableLength)
        {
            return new ChargerApple(cableLength);
        }
       
    }



K>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?


Уменьшаем и обобщаем кол-во кода.
Кодом людям нужно помогать!
Re[2]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 10:46
Оценка:
K>>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?

S>Уменьшаем и обобщаем кол-во кода.


ну и допустим клиенту надо создать фабрику для эпл. и собственно выдавать общие для всех производителей продуктов интерфейсы продуктов:

ICellPhone например? че-то не догоняю
Re[3]: Абстрактная фабрика и дженерики
От: Sharov Россия  
Дата: 20.08.19 11:00
Оценка: 2 (1) -1
Здравствуйте, Kaifa, Вы писали:



K>>>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?


S>>Уменьшаем и обобщаем кол-во кода.


K>ну и допустим клиенту надо создать фабрику для эпл. и собственно выдавать общие для всех производителей продуктов интерфейсы продуктов:


K>ICellPhone например? че-то не догоняю


var apple = factory.CreateInstance<CellPhoneApple>();
Кодом людям нужно помогать!
Re[4]: Абстрактная фабрика и дженерики
От: RushDevion Россия  
Дата: 20.08.19 11:15
Оценка: +2
S>var apple = factory.CreateInstance<CellPhoneApple>();
А чем это лучше new CellPhoneApple()?

Смысл абстрактной фабрики — дать клиенту возможность создавать объекты из семейства взаимосвязанных объектов.
При этом клиент не знает ни конкретные типы объектов (он работает с абстракциями), ни детали их конструирования.

А по теме: нет здесь смысла в дженериках, только код усложнишь.
Re[2]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 11:24
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Kaifa, Вы писали:


S>Навскидку как-то так:


S>
S>   public class AppleDevicesFactory : IDeviceFactory 
S>    {
S>        public T CreateInstance<T>() where T:new()
S>        {
S>            return new T();
S>        }

S>        public ICharger CreateCharger(int cableLength)
S>        {
S>            return new ChargerApple(cableLength);
S>        }
       
S>    }
S>



а можно на пальцах, зачем здесь требуется where T:new()
в доках какое-то мутное объяснение
Re[3]: Абстрактная фабрика и дженерики
От: Sharov Россия  
Дата: 20.08.19 11:34
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>а можно на пальцах, зачем здесь требуется where T:new()

K>в доках какое-то мутное объяснение

У типа T должен быть конструктор по умолчанию, т.е. без параметров.
Кодом людям нужно помогать!
Re[4]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 11:42
Оценка:
S>У типа T должен быть конструктор по умолчанию, т.е. без параметров.

это я прочитал в документации. а какой в этом практический смысл в данном случае? чтобы не падало при попытке использовать классы без конструктора по умолчанию? а это разве не будет отсечено на стадии компиляции?
Re[5]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 11:48
Оценка:
RD>А по теме: нет здесь смысла в дженериках, только код усложнишь.

притянуто за уши как учебное упражнение
Re[2]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 11:54
Оценка:
Здравствуйте, Sharov, Вы писали:

вопрос вдогонку. допустим среди устройств есть зарядник устройства, у которого метод создания имеет обязательный параметр — длина кабеля.
как это лучше реализовывать? наряду к абстрактному интерфейсу IAbstractDeviceFactoryMethod должен появиться такой же в общем-то независимый IAbstractChargerDeviceFactoryMethod?
или как это лучше вписать?
Re[3]: Абстрактная фабрика и дженерики
От: Ночной Смотрящий Россия  
Дата: 20.08.19 11:57
Оценка: +2
Здравствуйте, Kaifa, Вы писали:

K>вопрос вдогонку. допустим среди устройств есть зарядник устройства, у которого метод создания имеет обязательный параметр — длина кабеля.

K>как это лучше реализовывать? наряду к абстрактному интерфейсу IAbstractDeviceFactoryMethod должен появиться такой же в общем-то независимый IAbstractChargerDeviceFactoryMethod?
K>или как это лучше вписать?

Крайне рекомендую прочесть вот эту серию статей — https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Абстрактная фабрика и дженерики
От: Sharov Россия  
Дата: 20.08.19 11:58
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>это я прочитал в документации. а какой в этом практический смысл в данном случае? чтобы не падало при попытке использовать классы без конструктора по умолчанию? а это разве не будет отсечено на стадии компиляции?


Конкретно в данном случае почти все классы имеют конструктор по умолчанию. Иначе данный бы подход не сработал. На стадии компиляции будет отсечено.
Кодом людям нужно помогать!
Re: Абстрактная фабрика и дженерики
От: ksg71 Германия  
Дата: 20.08.19 13:13
Оценка: +2
Здравствуйте, Kaifa, Вы писали:


K>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?


ну разве что

public class DevicesFactory<TPhone, TCharger, ... > : IDeviceFactory
  where TPhone : ICellPhone, new()
  where TCharger : ICharger, new() 
   ...
    {
        public ICellPhone CreateCellPhone()
        {
            return new TPhone();
        }

        public ICharger CreateCharger()
        {
            return new TCharger();
        }

        ...
    }
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Отредактировано 20.08.2019 13:16 ksg71 . Предыдущая версия .
Re[3]: Абстрактная фабрика и дженерики
От: · Великобритания  
Дата: 20.08.19 14:13
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>вопрос вдогонку. допустим среди устройств есть зарядник устройства, у которого метод создания имеет обязательный параметр — длина кабеля.

Как я понимаю, как правило суть фабрики в том, чтобы абстрагироваться от способа создания объектов и их зависимостей. Поэтому как правило длина кабеля будет параметром (или константой) фабрики:
public ModernAppleDevicesFactory
{
    private ICellPhone theOnlyTruePhone = new IPhone();
    private int cableLength;

    public ModernAppleDevicesFactory(int cableLength) {this.cableLength = cableLength;}

    public ICellPhone CreateCellPhone()
    {
        return theOnlyTruePhone;
    }

    public ICharger CreateCharger()
    {
        return new MadeInChinaCharger(this.cableLength);
    }

    public ILaptop CreateLaptop()
    {
        return new LaptopApple(DisplayType.RETINA);
    }
}

Клиенты теперь могут не париться с выбором длины, модели, етс, фабрика полностью отвечает за выбор параметров конструктора и экземпляров.
Параметризированные методы Create* это более сложный случай и в целом да, нужно если разные типы имеют один и тот же параметр.
Ещё фабрики могут быть полезны, если надо делать выбор о том, что создавать новый объект или брать существующий.

K>как это лучше реализовывать? наряду к абстрактному интерфейсу IAbstractDeviceFactoryMethod должен появиться такой же в общем-то независимый IAbstractChargerDeviceFactoryMethod?

K>или как это лучше вписать?
Ну если применить ISP, то так оно и выйдет.

А генерики непонятно тут накой. Их надо использовать только если очень надо.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 20.08.2019 14:16 · . Предыдущая версия .
Re: Абстрактная фабрика и дженерики
От: VladCore  
Дата: 20.08.19 14:34
Оценка:
Здравствуйте, Kaifa, Вы писали:

Элементарно!

ICellPhone<IChargable,IStorage>
ILaptop<IChargable,IStorage>
ITablet<IChargable,IStorage>

IStorage может быть локальное или облачное, у каждого свои методы
Re[2]: Абстрактная фабрика и дженерики
От: Kaifa Россия  
Дата: 20.08.19 17:04
Оценка:
K>ну разве что

K>
K>public class DevicesFactory<TPhone, TCharger, ... > : IDeviceFactory
K>  where TPhone : ICellPhone, new()
K>  where TCharger : ICharger, new() 
K>   ...
K>    {
K>        public ICellPhone CreateCellPhone()
K>        {
K>            return new TPhone();
K>        }

K>        public ICharger CreateCharger()
K>        {
K>            return new TCharger();
K>        }

K>        ...
K>    }

K>



а как в TCharger параметр передать интовый?
Re[3]: Абстрактная фабрика и дженерики
От: ksg71 Германия  
Дата: 20.08.19 17:47
Оценка:
Здравствуйте, Kaifa, Вы писали:


K>>ну разве что


K>>
K>>public class DevicesFactory<TPhone, TCharger, ... > : IDeviceFactory
K>>  where TPhone : ICellPhone, new()
K>>  where TCharger : ICharger, new() 
K>>   ...
K>>    {
K>>        public ICellPhone CreateCellPhone()
K>>        {
K>>            return new TPhone();
K>>        }

K>>        public ICharger CreateCharger()
K>>        {
K>>            return new TCharger();
K>>        }

K>>        ...
K>>    }

K>>



K>а как в TCharger параметр передать интовый?



запихивать в конструктор фабрики Func<int, TСharger> и вызывать его внутри CreateCharger(int) как вариант
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[3]: Абстрактная фабрика и дженерики
От: Sharov Россия  
Дата: 20.08.19 17:48
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>а как в TCharger параметр передать интовый?


Я же выше объяснил -- только для типов с публичным конструктором по умолчанию.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.