доброе время суток уважаемым участникам форума!
В нашей компании есть маленькая программка, которая генерирует заказы нашим дилерам. большинство дилеров принимает заказы в нашей стандартной форме, но некоторые дилеры требует от нас, чтобы мы отправляли им заказы в их форме.
У нас есть абстрактный класс DealerOrderGenerator, от которого наследуются классы, обеспечивающие генерацию заказа дилеру в нужном формате, т.е. классы типа DefaultOrderGenerator, ComplexFormatOrderGenerator, SomeOtherCompanyNameOrderGenerator.
Нужно связать поставщика с определенным форматом заказа. Это можно сделать очень тупо:
DealerOrderGenerator CreateDealerOrderGenerator(Dealer dealer, Order order)
{
switch(dealer.Name)
{
case"CompanyName":
return new SomeOtherCompanyNameOrderGenerator(order);
case"AnotherCompanyName":
return new AnotherCompanyNameOrderGenerator(order);
default:
return new DefaultOrderGenerator(order);
}
}
понятно, что это не самый лучший дизайн для фабричного метода.
Можно заменить имена дилеров, на их ID — уже лучше, но тоже не хорошо.
Поэтому видимо надо напрячься и сделать у класса Dealer и в таблице Dealers поле OrderFormatID, а так же сделать таблицу OrderFormats. В коде же сделать enum OrderFormats, и результирующий код будет к примеру таким:
enum OrderFormats
{
Default = 1,
CompanyA = 2,
CompaniesBC = 3
}
DealerOrderGenerator CreateDealerOrderGenerator(Dealer dealer, Order order)
{
switch((OrderFormats)dealer.OrderFormatID)
{
case OrderFormats.CompanyA:
return new CompanyAOrderGenerator(order);
// и т.д.
}
}
но в этом случае все равно придется следить за тем чтобы значения в таблице OrderFormats и в enum'е OrderFormats не рассинхронизировались.
что уважаемые гуру думают о таком решении? или как-то можно сделать по другому, лучше и проще?
Здравствуйте, Studentik87, Вы писали:
S>но в этом случае все равно придется следить за тем чтобы значения в таблице OrderFormats и в enum'е OrderFormats не рассинхронизировались. S>что уважаемые гуру думают о таком решении? или как-то можно сделать по другому, лучше и проще?
Нормальное решение.
Только не забудьте констрейнт на поле повесить, чтобы не понавводили всякого.
Здравствуйте, Studentik87, Вы писали:
S>Нужно связать поставщика с определенным форматом заказа. Это можно сделать очень тупо:
S>
DealerOrderGenerator CreateDealerOrderGenerator(Dealer dealer, Order order)
S>{
S> switch(dealer.Name)
S> {
S> case"CompanyName":
S> return new SomeOtherCompanyNameOrderGenerator(order);
S> case"AnotherCompanyName":
S> return new AnotherCompanyNameOrderGenerator(order);
S> default:
S> return new DefaultOrderGenerator(order);
S> }
S>}
S>понятно, что это не самый лучший дизайн для фабричного метода. S>Можно заменить имена дилеров, на их ID — уже лучше, но тоже не хорошо. S>Поэтому видимо надо напрячься и сделать у класса Dealer и в таблице Dealers поле OrderFormatID, а так же сделать таблицу OrderFormats. В коде же сделать enum OrderFormats, и результирующий код будет к примеру таким: S>
enum OrderFormats
S>{
S> Default = 1,
S> CompanyA = 2,
S> CompaniesBC = 3
S>}
S>DealerOrderGenerator CreateDealerOrderGenerator(Dealer dealer, Order order)
S>{
S> switch((OrderFormats)dealer.OrderFormatID)
S> {
S> case OrderFormats.CompanyA:
S> return new CompanyAOrderGenerator(order);
S> // и т.д.
S> }
S>}
S>но в этом случае все равно придется следить за тем чтобы значения в таблице OrderFormats и в enum'е OrderFormats не рассинхронизировались. S>что уважаемые гуру думают о таком решении? или как-то можно сделать по другому, лучше и проще?
Совсем фиксировать имя клиента в коде не хорошо.
Если форматов фиксированное число и нет необходимости думать о том, что завтра появится еще одна компания со своим форматом, то можно добавить поле FormatGenetarorType и хранить там нужный тип генератора.
Если разница между компаниями есть, но формат фактически один и тот же, то можно добавить еще поле FormatGeneratorParams, где в XML формате хранить дополнительные настройки. Ну например тип ExcelGenerator, а в params будет описание столбцов.
Если завтра будет еще компания с другим форматом, то делать еще столбец GeneratorAssembly и хранить еще и имя dll в которой этот генератор хранится. Сделать интерфейс IGenerator с методом Generate(...) и потом докладывать нужные DLLки.
Здравствуйте, Studentik87, Вы писали:
S>но в этом случае все равно придется следить за тем чтобы значения в таблице OrderFormats и в enum'е OrderFormats не рассинхронизировались. S>что уважаемые гуру думают о таком решении? или как-то можно сделать по другому, лучше и проще?
Судя по коду — C#. Тогда reflection вам в помощь.
Определите интерфейс IOrderGenerator. Сделайте класс-фабрику которая принимает имя класса-реализации IOrderGenerator и выдает экземпляр интерфейса. Ну а в объектах "диллер" храните, как уже сказал adontz, имя класса-реализации генератора ордеров.
Здравствуйте, stump, Вы писали:
S>Определите интерфейс IOrderGenerator. Сделайте класс-фабрику которая принимает имя класса-реализации IOrderGenerator и выдает экземпляр интерфейса. Ну а в объектах "диллер" храните, как уже сказал adontz, имя класса-реализации генератора ордеров.
И молитесь, чтобы никто ничего не сломал при рефакторинге.
Re[3]: генерация заказов дилерам в разных форматах
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, stump, Вы писали:
S>>Определите интерфейс IOrderGenerator. Сделайте класс-фабрику которая принимает имя класса-реализации IOrderGenerator и выдает экземпляр интерфейса. Ну а в объектах "диллер" храните, как уже сказал adontz, имя класса-реализации генератора ордеров.
L>И молитесь, чтобы никто ничего не сломал при рефакторинге.
Никогда не молился при рефакторинге. Просто рефакторинг без юнит-тестов противопоказан. А с юнит-тестами и бояться нечего.
Здравствуйте, stump, Вы писали:
L>>И молитесь, чтобы никто ничего не сломал при рефакторинге. S>Никогда не молился при рефакторинге. Просто рефакторинг без юнит-тестов противопоказан. А с юнит-тестами и бояться нечего.
А они ничего и не обнаружат, сломается-то в продакшене.
Re[5]: генерация заказов дилерам в разных форматах
Здравствуйте, Lloyd, Вы писали:
L>А они ничего и не обнаружат, сломается-то в продакшене.
Чиниться за 5 минут, одним update запросом SQL. Причём в тексте сообщения Exception обязательно будет имя типа, экземпляр которого не удалось создать. Если денег на тестирование не дают, вполне приемлемая цена.
Здравствуйте, stump, Вы писали:
S>Судя по коду — C#. Тогда reflection вам в помощь. S>Определите интерфейс IOrderGenerator. Сделайте класс-фабрику которая принимает имя класса-реализации IOrderGenerator и выдает экземпляр интерфейса. Ну а в объектах "диллер" храните, как уже сказал adontz, имя класса-реализации генератора ордеров.
Зачем же сразу через рефлекщен (Смахивает на пальбу из пушки по воробьям).
Все же можно проще сделать через ServiceLocator или Repository (KISS же еще не отменили).
Там было написано русским по белому...
Re[3]: генерация заказов дилерам в разных форматах
Здравствуйте, C...R...a...S...H, Вы писали:
CRA>Зачем же сразу через рефлекщен (Смахивает на пальбу из пушки по воробьям). CRA>Все же можно проще сделать через ServiceLocator или Repository (KISS же еще не отменили).
Это как раз и не сложно.
А вот хранить имена сборок в БД
Поддерживать АssemblyBinding зраздел
Я уже молчу про необходимость деплоить сборки на которые не ссылается ни один проект
Есть у меня опыт такой вот plugin реализации.
В которой, для того что бы скомпилить только интерфейс, необходимо выполнять Build Solution, так как на плагины ни один проект не ссылается
А в другом проЖекте вообще в базе хранятся полные имена сборок
Там было написано русским по белому...
Re[5]: генерация заказов дилерам в разных форматах
Здравствуйте, C...R...a...S...H, Вы писали:
CRA>Здравствуйте, stump, Вы писали:
S>>Чет я суть проблемы нивкурю никак... CRA>Каой имеено проблемы??? CRA>Можно по конкретнее?
Ты пишешь про какие-то проблемы со сборкой деплоем и т.д.
Здравствуйте, adontz, Вы писали:
L>>А они ничего и не обнаружат, сломается-то в продакшене.
A>Чиниться за 5 минут, одним update запросом SQL. Причём в тексте сообщения Exception обязательно будет имя типа, экземпляр которого не удалось создать. Если денег на тестирование не дают, вполне приемлемая цена.
Лучше делать так, чтобы не ломалось. Вариант с enum-ом как раз из разряда таких.
Re[7]: генерация заказов дилерам в разных форматах
Здравствуйте, Lloyd, Вы писали:
A>>Чиниться за 5 минут, одним update запросом SQL. Причём в тексте сообщения Exception обязательно будет имя типа, экземпляр которого не удалось создать. Если денег на тестирование не дают, вполне приемлемая цена. L>Лучше делать так, чтобы не ломалось. Вариант с enum-ом как раз из разряда таких.
Вариант с enum'ом архитектурно, конечно, весь из себя замечательный, но на практике очень плохой. Представь себе, что генераторы заказов могут писать независимые разработчики.
Здравствуйте, adontz, Вы писали:
A>Вариант с enum'ом архитектурно, конечно, весь из себя замечательный, но на практике очень плохой. Представь себе, что генераторы заказов могут писать независимые разработчики.
Представил.
1) В чем будет проблема?
2) Чем вариант с хранением имени класса будет лучше?
Re[9]: генерация заказов дилерам в разных форматах
Здравствуйте, Studentik87, Вы писали:
S>Представил. S>1) В чем будет проблема?
Кто и как редактирует enum, если на момент его компиляции список генераторов не известен заранее?
S>2) Чем вариант с хранением имени класса будет лучше?