Сообщение Re[6]: Опциональные типы от 23.02.2017 11:30
Изменено 23.02.2017 11:30 vdimas
Re[6]: Опциональные типы
Здравствуйте, meadow_meal, Вы писали:
_>Здравствуйте, vdimas, Вы писали:
V>>Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
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)
_>
_>Нужно проверить, состоит ли игрок в клане. В каком из случаев очевидно, как это сделать, а в каком остается чесать репу?
Вот так будет очевидно:
_>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>>
_>Да. А что именно смущает? Я уже писал, этот код можно сгенерировать.
Смущает, что если это ручной код, то за это вон из профессии.
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:
А у вас случился синдром NIH.
Хотя огромное кол-во именно сетевых протоколов (Bluetooth, обмен SSL-сертификатами и т.д.) юзают ASN.1.
Он для этого и был придуман.
И он подходит для сетевого общения НАМНОГО лучше любого мыслимого IDL.
Ну разве что я бы понял единственный сценарий: разработка совсем простого проблемно-ориентированного языка описания данных (но не IDL) и генерацию из этого самописного языка ASN.1. И ву а ля.
_>Поэтому внешний IDL — это обязательное требование.
Насосанное из пальца, а не обязательное.
Не вы одни сетевые протоколы пишете.
_>Возни с ним нет. Это отработано годами.
Кошмар. Вот это поделие стоило годы человеколет?
Однозначно надо подавать на компенсацию убытков. ))
V>>Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
_>Так и приведенный код обновления полей я могу сгенерировать скриптом расширения к нашему кодогенератору строк так на восемь. Но хватает и тонкостей, например с обновлением коллекций (а там пока каждый второй случай — частный), поэтому проще в итоге писать руками.
Т.е. годы человеколет потрачены, а всё-равно маппинг данных на объекты происходит ручками. ЧТД.
_>Резюмируя: я просил привести альтернативы и описать проблемы с текущим решением. Две альтернативы ты привел, одна из них очень многословная и спорная (а компенсирующих преимуществ я пока не вижу). Вторая — грязноватый хак, уже опробованный на практике с негативным эффектом. А вот в чем проблема с текущим решением и его якобы тяжелой поддержкой ты так и не объяснил.
Самая главная у тебя проблема — это много недоговариваний, преувеличений и откровенного вранья в итоге. Вот уже выясняется, что твои Optional<Optional<ClanId>>, оказываются, никуда далее слоя "драйвера сетевого протокола" не пролезают и никому нафик не уперлись. У-у-упс? Причем, это тот слой, который должен быть автогенерён в любом случае, потому что именно там живёт куча ошибок у всех вот этих сетевых приблуд.
_>Здравствуйте, vdimas, Вы писали:
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>>, оказываются, никуда далее слоя "драйвера сетевого протокола" не пролезают и никому нафик не уперлись. У-у-упс? Причем, это тот слой, который должен быть автогенерён в любом случае, потому что именно там живёт куча ошибок у всех вот этих сетевых приблуд.
Re[6]: Опциональные типы
Здравствуйте, meadow_meal, Вы писали:
V>>Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
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)
_>
_>Нужно проверить, состоит ли игрок в клане. В каком из случаев очевидно, как это сделать, а в каком остается чесать репу?
Вот так будет очевидно:
_>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>>
_>Да. А что именно смущает? Я уже писал, этот код можно сгенерировать.
Смущает, что если это ручной код, то за это вон из профессии.
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:
А у вас случился синдром NIH.
Хотя огромное кол-во именно сетевых протоколов (Bluetooth, обмен SSL-сертификатами и т.д.) юзают ASN.1.
Он для этого и был придуман.
И он подходит для сетевого общения НАМНОГО лучше любого мыслимого IDL.
Ну разве что я бы понял единственный сценарий: разработка совсем простого проблемно-ориентированного языка описания данных (но не IDL) и генерацию из этого самописного языка ASN.1. И ву а ля.
_>Поэтому внешний IDL — это обязательное требование.
Насосанное из пальца, а не обязательное.
Не вы одни сетевые протоколы пишете.
_>Возни с ним нет. Это отработано годами.
Кошмар. Вот это поделие стоило годы человеколет?
Однозначно надо подавать на компенсацию убытков. ))
V>>Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
_>Так и приведенный код обновления полей я могу сгенерировать скриптом расширения к нашему кодогенератору строк так на восемь. Но хватает и тонкостей, например с обновлением коллекций (а там пока каждый второй случай — частный), поэтому проще в итоге писать руками.
Т.е. годы человеколет потрачены, а всё-равно маппинг данных на объекты происходит ручками. ЧТД.
_>Резюмируя: я просил привести альтернативы и описать проблемы с текущим решением. Две альтернативы ты привел, одна из них очень многословная и спорная (а компенсирующих преимуществ я пока не вижу). Вторая — грязноватый хак, уже опробованный на практике с негативным эффектом. А вот в чем проблема с текущим решением и его якобы тяжелой поддержкой ты так и не объяснил.
Самая главная у тебя проблема — это много недоговариваний, преувеличений и откровенного вранья в итоге. Вот уже выясняется, что твои Optional<Optional<ClanId>>, оказываются, никуда далее слоя "драйвера сетевого протокола" не пролезают и никому нафик не уперлись. У-у-упс? Причем, это тот слой, который должен быть автогенерён в любом случае, потому что именно там живёт куча ошибок у всех вот этих сетевых приблуд.
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>>, оказываются, никуда далее слоя "драйвера сетевого протокола" не пролезают и никому нафик не уперлись. У-у-упс? Причем, это тот слой, который должен быть автогенерён в любом случае, потому что именно там живёт куча ошибок у всех вот этих сетевых приблуд.