Форум
Философия программирования
Тема
Как правильно задавать вопросы
B
I
abc
U
X
3
X
3
H1
H2
H3
H4
H5
H6
Asm
C/C++
C#
Erlang
Haskell
IDL
Java
Lisp
MSIL
Nemerle
ObjC
OCaml
Pascal
Perl
PHP
Prolog
Python
Ruby
Rust
SQL
VB
Здравствуйте, AndrewVK, Вы писали: AVK>Здравствуйте, mrTwister, Вы писали: T>>Я совершенно не могу понять, что делает этот кусок кода: T>>[c#] T>>IInventoryCardObject invCardObj = invAfter.GetInventoryCardObject(); T>>if (invCardObj != null) T>>{ T>> var card = ((IPersistedObject)invCardObj).Master as IInventoryCardBase; T>> if (card is IAccrualAccountingInventoryCard) T>> Manager.DeleteObject((IPersistedObject)invCardObj); T>> else if (!cardsDeleteSet.Contains(card)) T>> invCardObj.Inventory = inv; T>>} T>>inv.ChangesHistory = null; T>>ChangeInventoryActualStateInDocuments(invAfter, inv); T>>Manager.DeleteObject((IPersistedObject)invAfter); T>>[/c#] T>>Это просто взрыв мозга :crash: AVK>Не вижу никакого взрыва. Этот код просто лапочка по сравнению с тем, что местами попадается, скажем, в решарпере :) Типа нескольких вложенных циклов по графу, на который наложены и неявно учитываются контролируемые только в рантайме ограничения, внутри которых несколько goto, причем в разные точки. Вот это да, взрыв моска. А тут линейная логика. AVK>Ну давай посмотрим: AVK>[c#] AVK>IInventoryCardObject invCardObj = invAfter.GetInventoryCardObject(); AVK>[/c#] AVK>Получаем объект инвентаризации из истории операции инвентаризации AVK>[c#] AVK>if (invCardObj != null) AVK>[/c#] AVK>Если объект есть AVK>[c#] AVK>var card = ((IPersistedObject)invCardObj).Master as IInventoryCardBase; AVK>[/c#] AVK>Берем карточку, по которой он инвентаризован AVK>[c#] AVK>if (card is IAccrualAccountingInventoryCard) AVK> Manager.DeleteObject((IPersistedObject)invCardObj); AVK>[/c#] AVK>Здесь мои скудные знания бухгалтерии меня подводят, но суть понятна - удаляем объект инвентаризации, если он к определенному виду принадлежит. Прикладники тут, кстати, накосячили - приведение лишнее. AVK>[c#] AVK>else if (!cardsDeleteSet.Contains(card)) AVK> invCardObj.Inventory = inv; AVK>[/c#] AVK>Иначе проверяем наличие в хешике, который мы чуть раньше заполняли, и если совпало, то в детейле инвентарной карточки заменяем ссылку на справочник инвентаризуемых объектов. AVK>[c#] AVK>inv.ChangesHistory = null; AVK>[/c#] AVK>Обнуляем историю инвентаризации AVK>[c#] AVK>ChangeInventoryActualStateInDocuments(invAfter, inv); AVK>[/c#] AVK>Название метода вполне говорящее. AVK>[c#] AVK>Manager.DeleteObject((IPersistedObject)invAfter); AVK>[/c#] AVK>Удаляем инвентаризационную операцию AVK>Это, собственно, типичная бизнес-логика. Далеко не самая запутанная, уж поверь. И ее то как раз нужно сохранить, это входящее требование. А вот как ее более красиво записать - вопрос. AVK>>>Не куча, а несколько. И это особенность платформы. Можешь просто проигнорировать. T>>Я насчитал 11 явных и неявных даункастов. AVK>Где? В DeleteObject даункаст лишний. Даункаст при обращении к Master - технологическая особенность, связанная с распределенностью системы и едиными интерфесами и в клиентском и в серверном коде. Согласен, проблема, но ее не так то легко вылечить. А as/is - это просто проверка дискриминанта, который выражен в виде реализации тех или иных интерфейсов. AVK>>>Непонятно. Современные БД в принципе увязаны с null. T>>Совсем не обязательно тащить в прикладной код бизнес-логики потроха и особенности работы с БД. AVK>Согласен. Но альтернатив как то недофига. Можно, наверное, maybe monad использовать, да. Но тут скорее не dsl нужен, а нормальный допил C#. Штука то предельно универсальная. T>>>>а во второй оставили низкоуровневый лапшу-код AVK>>>Почему низкоуровневый? T>>Потому что API вашей платформы выглядит весьма гибким и низкоуровневым, о чем свидетельствует, например, обилие даункастов. AVK>Это не API платформы, это сознательно сделанные на прикладном уровне решения. API платформы это Get и DeleteObjects. T>>>>*]Использование бессмысленных идентификаторов AVK>>>Каких именно? T>>obj AVK>InventaryObject это потому что оно так и называется - [b]объект[/b] инвентаризации, а не потому что это какая то неведомая фигня типа System.Object. Так что вполне осмысленный. T>>>>*]Можно было бы обойтись без модификаций локальной переменной (cardsDeleteSet) AVK>>>Зачем? T>>Чтобы код было легче читать. Сейчас чтобы понять, что происходит приходится искать все места использования переменной в весьма "жирном" коде, искать, где переменная модифицируется, а где затем читается. AVK>Переменная модифицируется ровно один раз, при объявлении. Потом меняется содержимое самого хеша, а не переменной. И использование вполне стандартное - запоминаем в цикле обхода, потом запомненное используем для проверки. Такого кода, скажем, внутри System.Enumerable до попы, хотя, вроде как, весьма приличные спецы писали. T>>Вообще, я бы отрефакторил код, чтобы он в конце-концов выглядел как-то так: T>>[c#] T>>var documentsAndInventories = ( T>> from document in Manager.Get(objectsIds) T>> from inventory in document.GetObjects().Cast<IInventory> T>> select new {document, inventory} ).ToArray(); AVK>Можно. Но линк для прикладников, все же, тяжеловат. Со временем, впрочем, должны научится, сейчас довольно вменяемых товарищей набрали. Было намного хуже, уж поверь. T>>var inventories = (from item in documentsAndInventories select new {item.inventory}).ToArray(); AVK>... AVK>Спасибо за потраченное время.
Теги:
Введите теги разделенные пробелами. Обрамляйте в кавычки словосочетания с пробелами внутри, например:
"Visual Studio" .NET
Имя, пароль:
Загрузить
Нравится наш сайт?
Помогите его развитию!
Отключить смайлики
Получать ответы по e-mail
Проверить правописание
Параметры проверки …