Re[6]: Опциональные типы
От: vdimas Россия  
Дата: 23.02.17 11:30
Оценка:
Здравствуйте, meadow_meal, Вы писали:

V>>Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:

V>>
V>>enum ClanUpdate { NoUpdate, EnterClan, ExitClan };

V>>union ClanEvent switch (ClanUpdate) { 
V>>       case NoUpdate: ; 
V>>       case EnterClan: int ClanId; 
V>>       case ExitClan: ; 
V>>}; 
V>>


_>Сразу вопросы:


_>1) А для обязательных полей ты тоже рекомендуешь объявлять enum и union? Или мы обязательные поля обновляем одним способом, а опциональные другим?


Я уже ответил тебе исчерпывающе.

1. Идея использовать union — она твоя, я лишь показал кривизну этого сценария с Opntional<Optional<ClanId>>.

2. Затем предложил еще два варианта упаковки сообщений и даже дал тебе как раз сценарий из сетевых дров БД, когда в одном потоке иду обязательные и необязательные поля.


_>Если так, то разве это — не проблема сопровождения? (Для меня одно из базовых требований при выборе паттерна — то, что придет новый человек и сможет сходу решать любую простую задачу "по аналогии".)


А я тебе предложил взять BLToolkit и всё что потребуется сделать новому человеку — это правильно расставить атрибуты в добавляемых/исправляемых структурах и их полях.


_>2) Вот эти 6 лишних строк и один-два типа на ровном месте для каждого поля — вот ради чего это?


Чтобы пришедшие после тебя не материли тебя, не проклинали, не выбросили нахрен твоё поделие и не писали своё.


_>У меня сейчас 1 бит в хедере + 1 байт для поля. Свести к двум битам — не проблема, только вот единственным наблюдаемым эффектом будет усложнение документации по бинарному протоколу.


Если у тебя 1 бит в заголовке, то ты морочишь мне голову и насчет IDL и насчет Optional.
Получается, насосал из пальца несуществующий сценарий.


_>Это хуже по следующим причинам:

_>1) Игрок больше не состоит в клане — это не тоже клан такой. Из него выйти нельзя, он в UI не отображается, у него нет ни одного атрибута клана. Я считаю, что если это различие можно выразить в системе типов, то его нужно выразить.

Для этого надо, чтобы язык такое позволял, а дотнет тебе такое НЕ позволит. В системе типов дотнета у тебя всегда будет Optional<ClanId> — т.е. алгебраическая сумма всех валидных значений ClanId плюс одно специальное.

А у тебя точно ВСЕ допустимые значения ClanId будут являться валидными?



_>2)

_>
_>public class Player
_>{
_>    // 1
_>    public int ClanID { get; private set; }
_>    // 2
_>    public int? ClanID { get; private set; }
_>}
_>

_>Нужно проверить, состоит ли игрок в клане. В каком из случаев очевидно, как это сделать, а в каком остается чесать репу?


Вот так будет очевидно:
enum ClanId {
    NotSet = 0;
}


_>3) Теперь для каждого случая обновления опционального по своей природе поля мы будем придумывать новый хак?


Т.е. ты не понял ни строчки из сообщения, на которое отвечаешь? ))


_>На самом деле это мы как раз пробовали в первую очередь. Люди плевались и просили Optional<Optional<>>.


Из пальца вытяжки пошли уже. ))
Потому что чаще люди плюются на вложенность Optional.
И вообще на любую вложенность.


V>>И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.

_>Вот это называется унифицированно? Когда на каждый чих нужно придумывать клан который не клан?

А как же они пользуются методом IndexOf, бедные, если оно возвращает специальное значение -1?


V>>Ты в сетку как передаёшь?

V>>По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно?
_>По биту.

ЧТД. Наврал с три короба про IDL.
Итого, в отсутствии IDL-компилятора ты предлагаешь ручками оперировать с discriminated union?
И после этого у тебя поднимается рука обвинять кого-то в сложности?


V>>В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.

_>А как в 2017 нужно описывать сетевой протокол с поддержкой сериализации для разных языков и форматов и возможностью генерации схемы?

Нет это ты мне ответь, как ты умудрился в IDL закодировать Optional через один бит.


_>IDL внутренней разработки.


Т.е. вы разработали синтаксический и семантический анализатор собственной версии IDL, а так же кодогенератор для разных языков, а так же для каждого из языков разработали однозначные правила маппинга типов вашего IDL на типы языка. Я ничего не пропустил?

Ребят, вы динамите инвестора, реально.
Занимаетесь не делом, а тем, что вам интересно — побочными какими-то вещами.
И после этого у тебя хватает совести задавать вопросы из разряда:

Когда на каждый чих нужно придумывать клан который не клан?




V>>И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:

V>>
V>>void Update(XxxUpdate update)
V>>{
V>>    if (update.Field1.HasValue)
V>>        this.Field1 = update.Field1.Value; 
V>>    if (update.Field2.HasValue)
V>>        this.Field2 = update.Field2.Value;
V>>...
V>>


_>Да. А что именно смущает? Я уже писал, этот код можно сгенерировать.


Смущает, что если это ручной код, то за это вон из профессии.
ORM слышал?
Ручками в 2017-м не принято.

А если это автогенерённый код, то вон из профессии уже за применение Optional в сугубо внутреннем промежуточном типе XxxUpdate, который живет сугубо в недрах вашего сетевого "драйвера".

В общем, автогенерённому коду никакой Optional и даром не нужен. Автогенерённый код может пробегаться прямо по битовой маске и не допускать ошибок из разряда "опять человеческий фактор подвёл".


V>>Когда полей посылается много, то можно вначале прогнать битовую маску.

_>Для дельта-рекордов мы так и делаем.

А для обновления отдельных полей или их групп лучше ввести отдельные же сообщения { MessageId, field1, field2 }. Или унифицировать до пар { FieldId, field }, но передавать не попарно, а сначала все FieldId из пакета, а потом все поля. Потому что FieldId можно упаковывать в битовую ширину меньше байта.


V>>Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.

_>Нельзя. У ASN.1 крайне неудобный язык и нет возможности удобно контролировать кодогенерацию через атрибуты.

Чего-чего???
Определение структур и union в ASN.1 практически точно такое же, как в IDL.

А уж за ручную кодогенерацию на разные языки из своей "версии" IDL на месте инвестора я бы с вами уже судился на компенсацию убытков.


_>Я писал, что сервер у нас на Эрланге.


Тем более.
Можно описать поля в виде того же "JSON без кавычек", и не париться с разработкой парсера.

Ведь вам из всей функциональности IDL требуется описать только типы данных, но не интерфейсы.
Так с какого боку вы потратили кучу ресурсов на Interface Definition Language?

Тем более, что именно под Эрланг и именно под дотнет есть сразу несколько хороших решений ASN.1.
И твой аргумент насчет XML:

ASN.1 standard XML Encoding Rules (XER) makes it possible for messages defined using ASN.1 to be encoded in XML format.


А у вас случился синдром NIH.
Хотя огромное кол-во именно сетевых протоколов (Bluetooth, обмен SSL-сертификатами и т.д.) юзают ASN.1.
Он для этого и был придуман.
И он подходит для сетевого общения НАМНОГО лучше любого мыслимого IDL.

Ну разве что я бы понял единственный сценарий: разработка совсем простого проблемно-ориентированного языка описания данных (но не IDL) и генерацию из этого самописного языка ASN.1. И ву а ля.


_>Поэтому внешний IDL — это обязательное требование.


Насосанное из пальца, а не обязательное.
Не вы одни сетевые протоколы пишете.


_>Возни с ним нет. Это отработано годами.


Кошмар. Вот это поделие стоило годы человеколет?
Однозначно надо подавать на компенсацию убытков. ))


V>>Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.

_>Так и приведенный код обновления полей я могу сгенерировать скриптом расширения к нашему кодогенератору строк так на восемь. Но хватает и тонкостей, например с обновлением коллекций (а там пока каждый второй случай — частный), поэтому проще в итоге писать руками.

Т.е. годы человеколет потрачены, а всё-равно маппинг данных на объекты происходит ручками. ЧТД.


_>Резюмируя: я просил привести альтернативы и описать проблемы с текущим решением. Две альтернативы ты привел, одна из них очень многословная и спорная (а компенсирующих преимуществ я пока не вижу). Вторая — грязноватый хак, уже опробованный на практике с негативным эффектом. А вот в чем проблема с текущим решением и его якобы тяжелой поддержкой ты так и не объяснил.


Самая главная у тебя проблема — это много недоговариваний, преувеличений и откровенного вранья в итоге. Вот уже выясняется, что твои Optional<Optional<ClanId>>, оказываются, никуда далее слоя "драйвера сетевого протокола" не пролезают и никому нафик не уперлись. У-у-упс? Причем, это тот слой, который должен быть автогенерён в любом случае, потому что именно там живёт куча ошибок у всех вот этих сетевых приблуд.
Отредактировано 23.02.2017 11:30 vdimas . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.