Вот рассмотрим простейшую учебную:
есть бренды электроники.
для каждого бренда несколько девайсов (мобильник, планшет)
для простоты ограничим функционал включением.
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();
}
}
Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?
public class AppleDevicesFactory : IDeviceFactory
{
public T CreateInstance<T>() where T:new()
{
return new T();
}
public ICharger CreateCharger(int cableLength)
{
return new ChargerApple(cableLength);
}
}
K>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?
K>>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?
S>Уменьшаем и обобщаем кол-во кода.
ну и допустим клиенту надо создать фабрику для эпл. и собственно выдавать общие для всех производителей продуктов интерфейсы продуктов:
K>>>Собственно куда здесь, на каком уровне и самое главное преследуя какую цель можно вкорячить дженерики и какие от этого будут преимущества?
S>>Уменьшаем и обобщаем кол-во кода.
K>ну и допустим клиенту надо создать фабрику для эпл. и собственно выдавать общие для всех производителей продуктов интерфейсы продуктов:
K>ICellPhone например? че-то не догоняю
var apple = factory.CreateInstance<CellPhoneApple>();
S>var apple = factory.CreateInstance<CellPhoneApple>();
А чем это лучше new CellPhoneApple()?
Смысл абстрактной фабрики — дать клиенту возможность создавать объекты из семейства взаимосвязанных объектов.
При этом клиент не знает ни конкретные типы объектов (он работает с абстракциями), ни детали их конструирования.
А по теме: нет здесь смысла в дженериках, только код усложнишь.
Здравствуйте, 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()
в доках какое-то мутное объяснение
S>У типа T должен быть конструктор по умолчанию, т.е. без параметров.
это я прочитал в документации. а какой в этом практический смысл в данном случае? чтобы не падало при попытке использовать классы без конструктора по умолчанию? а это разве не будет отсечено на стадии компиляции?
вопрос вдогонку. допустим среди устройств есть зарядник устройства, у которого метод создания имеет обязательный параметр — длина кабеля.
как это лучше реализовывать? наряду к абстрактному интерфейсу IAbstractDeviceFactoryMethod должен появиться такой же в общем-то независимый IAbstractChargerDeviceFactoryMethod?
или как это лучше вписать?
Здравствуйте, Kaifa, Вы писали:
K>вопрос вдогонку. допустим среди устройств есть зарядник устройства, у которого метод создания имеет обязательный параметр — длина кабеля. K>как это лучше реализовывать? наряду к абстрактному интерфейсу IAbstractDeviceFactoryMethod должен появиться такой же в общем-то независимый IAbstractChargerDeviceFactoryMethod? K>или как это лучше вписать?
Здравствуйте, Kaifa, Вы писали:
K>это я прочитал в документации. а какой в этом практический смысл в данном случае? чтобы не падало при попытке использовать классы без конструктора по умолчанию? а это разве не будет отсечено на стадии компиляции?
Конкретно в данном случае почти все классы имеют конструктор по умолчанию. Иначе данный бы подход не сработал. На стадии компиляции будет отсечено.
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
Здравствуйте, 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, то так оно и выйдет.
А генерики непонятно тут накой. Их надо использовать только если очень надо.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай