Как стать автором
Обновить
17
0
Попов Сергей @f0bos

Пользователь

Отправить сообщение
Вы не нашли решения проблемы? Или может быть видели где-нибудь пример реализации ISpecification в терминах доменной модели(не объектов EF)?
Я считал что грамматика и пунктуация разные вещи.
PS. веткой промазал.
Я, пошёл за хлебом

Вот хоть убейте, в чем проблема?
Может быть вы меня не так поняли, я имел ввиду что когда мы пытаемся упаковать в конкретный транспорт разные типы сообщений(которые приходят в виде обобщенного класса/интерфейса) я не вижу способа избежать typeof. А если пытаться впихнуть детали транспорта пусть даже в DTO, то во-первых, специфичный код транспорта начинает размазываться, а во вторых с увеличение числа различных транспортов эти DTO начинают превращаться в свалку.
Мне как-то не очень нравится вариант с внесением специфичной для транспорта логики в DTO и для меня остается вариант с typeof, что мне очень не нравится.
Double dispatch в лице Visitor позволяет решить проблему typeof и загрязнения DTO деталями транспорта. Вся транспорто-специфичная логика уходит в Visitor.
Хотел уточнить у вас какой подход вы практикуете для работы с объектами разных классов с разными интерфейсами?
Например, у нас есть сервис, который получает команды от пользователя и отдает ему ответ. Притом сами запросы и ответы статичны и определены в доменной модели, меняется всего лишь транспорт доставки ответа клиенту. Хотелось бы чтобы доменная модель при возврате ответа играла роль Producer, а конкретный транспорт Consumer. И хотелось бы чтобы Producer генерировал «рабочие элементы» в каком-то обобщенном виде. В таком случае Consumer видит только некий базовый класс/интерфейс ClientResponseBase. И хотелось бы не смешивать иерархию ClientResponseBase с конкретными транспортами. И Vizitor имеет свои плюсы, есть возможность запихнуть всю логику упаковки всех вариантов ответа для одного конкретного транспорта в один класс и она больше не всплывет нигде.
Если не сложно поделитесь опытом решения схожих задач.
Я извиняюсь за приступ некрофилии, мне кажется что в вашем случае это не double dispatch. Как гласит Википедия
In software engineering, double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call.

У вас же все типы объектов известны на стадии компиляции. Диспетчеризацией и не пахнет. В англоязычной вики есть простой пример именно double dispatching.
Не-не, вы меня как-то не так поняли. В заголовке моей статьи не было фраз типа «80% продакшн кода написано некорректно» или чего-то похожего. Эту статью можно отнести к категории Tips & Tricks, или даже как пример вопроса на собеседовании на предмет определения уровня понимания дотнета. Меня позабавил тот факт, что ответив на автомате сам себе на «вопрос» из книги, я ошибся, вот и решил поделиться «радостью».
Я преднамеренно использовал HashSet, вопрос ключей здесь не стоял.
Цель статьи всего лишь показать грабли на которые можно наступить.
Да это все понятно, но сама система «растет» уже лет эдак 8, представляете какое это наследие? Да и работаем мы с кучей сторонних процессингов, терминалов. Вот так взять и запилить фичу это дороговато будет. Тут как в бойцовском клубе: пока сумма выплат по страховке меньше стоимости отзыва серии автомобилей — делать ничего не будем.
Как раз работаю в похожей системе, и у нас есть возможность посмотреть статус платежа по ID, который, можно сказать, инкрементируется, т.е. легко подбираем.
Но это диктуется удобством пользователя, если Вы положили деньги в терминале и хотите узнать статус платежа — то Вы можете просто зайти на сайт и по номеру чека получит эту инфу. Удобно. Никаких регистраций. Да и стали бы Вы регистрироваться на сайте владельца терминала только для того, чтобы узнать статус платежа.
С другой стороны есть проблемы с безопасностью(причем, с точки зрения менеджеров, незначительные). Не могу сказать как у нас принимали окончательное решение об этой фиче, какие варианты рассматривали, но работает оно так.
Ну да, делов-то, ведь уже, аж, целых два года. Вполне может белыми Королевский гамбит гонять, а черными контратаку Маршалла со старушечкой. Если мне не изменяет память ни один из чемпионов мира(каждый из которых своего рода гений) не начал играть в столь юном возрасте.
Насчет сервиса платежей, думал также как Вы пока не устроился работать в один из них. Это был достаточно крупный «сервис», но качество кода меня сильно удивило. Там были и методы 300+ строк, методы поменьше, но с количеством условных конструкций под 40-50. Кучи спагетти-кода. Просто магические или даже загадочные места. В плюс ко всему была куча мест которые алгоритм проведения платежа реализовывали по-разному и правильных вариантов было очень мало. Я это к тому, что МОЯ практика показывает, что говнокода полно и в «сервисах по загрузке кода» и в «платежных системах», а любую надежность можно обеспечить человеческим фактором. Не прошел платеж? Сейчас наш программист вручную проверит что с ним случилось — и этом способ работает.
По памяти:
Вы можете даже вообще эту сборку выкинуть из папки(только в том случае, когда из сборки используется только эта константа) — сборка даже не будет подгружаться. Соответственно, после компиляции можете подменять эту сборку сколько захотите и как захотите.
Также(да, мне нечем заняться с утра :)), не контролируется длина полей ввода. Если вводить в них достаточно длинные строки, то выводятся ошибки.
Например, вот тут:
var error = deserializer.Deserialize<YandexError>(response);
throw new YandexLinguisticsException(error);

Метод Deserialize может вернуть null(при длинной введенной строке), и в строке результата вижу:

System.NullReferenceException: Object reference not set to an instance of an object. at YandexLinguistics.NET.YandexLinguisticsException..ctor(YandexError error) in c:\Users\юленька\Documents\Code\Yandex-Linguistics.NET\YandexLinguistics.NET\YandexLinguisticsException.cs:line 12 at YandexLinguistics.NET.Dictionary.Lookup(LangPair lang, String text, String ui, LookupOptions flags) in c:\Users\юленька\Documents\Code\Yandex-Linguistics.NET\YandexLinguistics.NET\Dictionary\Dictionary.cs:line 69 at YandexLinguistics.NET.Gui.frmMain.<UpdateDictionaryResult>b__13() in c:\Users\юленька\Documents\Code\Yandex-Linguistics.NET\YandexLinguistics.NET.Gui\frmMain.cs:line 332
Ну до «наггета» еще далеко.

Вообще выглядят странными конструкции вида:

public class Dictionary
{
	protected RestClient _client = new RestClient("https://dictionary.yandex.net/api/v1/dicservice/");
	protected string _key;
...
}

В классе у которого нет наследников.

А если брать глобальнее, то:
1. Отсутствие асинхронного API
2. Куча повторяющихся кусков кода, как то:

RestRequest request = new RestRequest("getLangs");
request.AddParameter("key", _key);

RestResponse response = (RestResponse)_client.Execute(request);
XmlAttributeDeserializer deserializer = new XmlAttributeDeserializer();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
	var strs = deserializer.Deserialize<List<string>>(response);
	var allLangs = (Lang[])Enum.GetValues(typeof(Lang));
	Lang[] result = allLangs.Where(lang => strs.Contains(lang.ToString().ToLowerInvariant())).ToArray();
	return result;
}
else
{
	var error = deserializer.Deserialize<YandexError>(response);
	throw new YandexLinguisticsException(error);
}


Или вот такой паттерн, встречается многократно

RestResponse response = (RestResponse)_client.Execute(request);
XmlAttributeDeserializer deserializer = new XmlAttributeDeserializer();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
	...
}
else
{
	...
}

Это все, явные кандидаты на какое-то абстрагирование.

3. Хоть гуевое приложение в «наггет» не пойдет, но в нем все сетевые вызовы синхронны.
Итак: статический конструктор вызывается перед доступом к любому члену класса, за исключением констант.

Это происходит потому что компилятор «инлайнит» значения констант. У Рихтера можно почитать про разницу статических полей и констант.
Там не используется LinkedList, способ внутреннего хранения таймеров схож с работой LinkedList. Раз такой интерес к этому способу хранения, я допишу об этом позже.
Так как проект запущен в режиме «Debug» то все эти переменные будут «живы» до выхода из метода.

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность