Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Подарки от программис'тов

6208   4 5 6 7 8 9 10 11 12 13 14 все
Программист коренной житель26.07.22 14:20
NEW 26.07.22 14:20 
в ответ alex445 26.07.22 13:42
В чём прикол делать приватный словарь, а потом публичные методы доступа к нему GetValue и SetValue, которые просто достают данные из словаря и помещают их в него?

Тут может быть 3 варианта:

1) написавший это пришел из C++ и на момент написания еще не перестроился :)

2) GetValue и SetValue изменяют стандартное поведение словаря. Например GetValue проверяет, есть ли ключ и возвращает null, если ключа нет (стандартное поведение - кинуть исключение KeyNotFoundException) или при SetValue запретить перезаписывание уже имеющегося ключа.

3) Скрыть используемые контейнер. Например для того, чтобы можно было легко заменить контейнер без изменения внешнего интерфейса.

Программист коренной житель26.07.22 14:28
NEW 26.07.22 14:28 
в ответ alex445 26.07.22 14:00
Ещё такой подарок. В одном месте данное называется FileName. Потом оно передаётся в другое место, и там оно уже - FormName. Далее в третьем месте присваивается - уже SessionState (не спрашивайте про логику названия). Чтобы понять, что состояние сессии в поле таблицы в БД - это на самом деле имя файла формы в проекте - надо перелопатить кучу кода и отследить кучу присваиваний.

Скорее всего это писали несколько разработчиков и/или в разное время. Поэтому использовали разную терминологию. Я бы сказал, что это косяк проектирования. Или даже побочный эффект от отсутствия проектирования :)


Или вот циклическое владение друг другом. Форма имеет ссылку на сессию, а сессия - на форму. Связь 1 к 1. Нахрена?!

Для более удобного доступа к данным. Такое очень часто встречается. Ничего ужасного в этом нет. Типичные юз-кейсы: 1) если сессия стала невалидной, то надо закрыть окно. Для этого из сессии должна быть ссылка на окно. 2) Окно должно предупредить о скором истечении времени сессии, для это окно должно иметь ссылку на сессию :)


alex445 коренной житель26.07.22 14:47
NEW 26.07.22 14:47 
в ответ Программист 26.07.22 14:28, Последний раз изменено 26.07.22 14:48 (alex445)


Или вот циклическое владение друг другом. Форма имеет ссылку на сессию, а сессия - на форму. Связь 1 к 1. Нахрена?!
Для более удобного доступа к данным. Такое очень часто встречается. Ничего ужасного в этом нет. Типичные юз-кейсы: 1) если сессия стала невалидной, то надо закрыть окно. Для этого из сессии должна быть ссылка на окно. 2) Окно должно предупредить о скором истечении времени сессии, для это окно должно иметь ссылку на сессию :)

Тогда по сути это один объект. Не лучше собрать всё это под одним классом и использовать как поля (т.е. поле формы и поле сессии, а не поля этих классов в одном классе), чем циклы владения создавать? Я привык к иерархии наследования или владения, а не к циклическим зависимостям. Где потоки управления, кто на ком стоял? И если в наследовании циклы запретили по дизайну, то во владении говнокодеры могут себе насоздавать сиюминутных "удобных" юз-кейсов, что потом не разберёшься.

alex445 коренной житель26.07.22 14:49
NEW 26.07.22 14:49 
в ответ alex445 26.07.22 14:47

А как убить объект с циклическим владением? Ну, с точки зрения деструктора?

alex445 коренной житель26.07.22 15:05
NEW 26.07.22 15:05 
в ответ Программист 26.07.22 14:20, Последний раз изменено 26.07.22 15:12 (alex445)
В чём прикол делать приватный словарь, а потом публичные методы доступа к нему GetValue и SetValue, которые просто достают данные из словаря и помещают их в него?
Тут может быть 3 варианта:
1) написавший это пришел из C++ и на момент написания еще не перестроился :)
2) GetValue и SetValue изменяют стандартное поведение словаря. Например GetValue проверяет, есть ли ключ и возвращает null, если ключа нет (стандартное поведение - кинуть исключение KeyNotFoundException) или при SetValue запретить перезаписывание уже имеющегося ключа.
3) Скрыть используемые контейнер. Например для того, чтобы можно было легко заменить контейнер без изменения внешнего интерфейса.

Щас глянул - при добавлении значения SetValue проверяет, есть ли уже такой ключ, и если да, то меняет значение по ключу. Если нет - добавляет новый ключ и значение через метод Add словаря. Стандартный словарь кидает исключение, если ключ уже есть. Однако, точно такого же поведения можно добиться, просто используя индекс - он тоже добавляет ключ и значение, если ключа нет, и обновляет значение, если ключ есть. Т.е. программист, похоже, просто не знал о таком свойстве индекса словаря, иначе бы не стал заморачиваться с добавлением значения через метод Add, а не через индекс.


Вот, посмотрел - эта особенность индекса словаря существовала ещё минимум со времён Дотнета 2.0

6 - https://docs.microsoft.com/en-us/dotnet/api/system.collect...

2.0 - https://docs.microsoft.com/en-us/dotnet/api/system.collect...


Метод GetValue же просто берёт значение по индексу, никак это не обрабатывая - т.е. если индекса (ключа) нет, то словарь кидает исключение, а класс-обёртка над словарём с ним ничего не делает.


Т.е. вся портянка GetValue-SetValue просто переписывает логику индекса словаря. А ещё это же и в интерфейсе сделано. А к нему - тесты. И тесты тупо тестируют дефолтный словарь.


Остаётся вариант со скрытием имплементации. Но здесь явно пахнет преждевременными оптимизациями. Я думаю, остаётся "программист не знал" как самый вероятный вариант.

Программист коренной житель26.07.22 15:30
NEW 26.07.22 15:30 
в ответ alex445 26.07.22 14:47
Тогда по сути это один объект.

Нет, у каждого класса есть своя зона ответственности.


Не лучше собрать всё это под одним классом и использовать как поля (т.е. поле формы и поле сессии, а не поля этих классов в одном классе)

Поздравляю, ты изобрел божественный объект.


Я привык к иерархии наследования или владения, а не к циклическим зависимостям.

Я так понимаю, что двунаправленных списков и других моделей ты никогда не встречал :) Ну это скорее твоя беда.

MrSanders коренной житель26.07.22 15:31
NEW 26.07.22 15:31 
в ответ Программист 26.07.22 14:28
Я бы сказал, что это косяк проектирования. Или даже побочный эффект от отсутствия проектирования :)

Как только в игре возникает БД, количество вариантов увеличивается... Раньше в БД в SessionState действительно хранилось состояние сессии. Какое-то. Потом прорефакторили и поняли что оно нам нафиг не надо. А нужно имя формы. Но переименовывать столбец в БД... Это же геморрой! Надо во всех базах переименовать... А если ещё за БД отвечает другой отдел, которому для любого изменения надо заполнить 30-и страничный формуляр... Да ну нафиг! И остаётся поле SessionState. Менеджмент доволен, база стабильна! :)

Только что из поля GESCHSPEZ выуживал ID адреса для контакта. Который в коде везде ansprechpartnerId. Так и живём.

Программист коренной житель26.07.22 15:34
NEW 26.07.22 15:34 
в ответ alex445 26.07.22 14:49
А как убить объект с циклическим владением? Ну, с точки зрения деструктора?

Как сделаешь, так и будет. За это программистам и платят зарплату ;)

Программист коренной житель26.07.22 15:36
NEW 26.07.22 15:36 
в ответ alex445 26.07.22 15:05
Я думаю, остаётся "программист не знал" как самый вероятный вариант.

Или это было написано до .Net 2.0 или код был перенесен из плюсов.

Не надо думать, что другой программист чего-то не знал. Возможно, чего-то не знаешь ты ;)

alex445 коренной житель26.07.22 17:13
NEW 26.07.22 17:13 
в ответ Программист 26.07.22 15:30
Тогда по сути это один объект.

Нет, у каждого класса есть своя зона ответственности.


Не лучше собрать всё это под одним классом и использовать как поля (т.е. поле формы и поле сессии, а не поля этих классов в одном классе)

Поздравляю, ты изобрел божественный объект.

И то, и то - божественный объект. Оттого, что вы разобьёте один класс на два, но очень связанных, от божественности вы не избавитесь. Зато усложнится понимание и управление этими сиамскими близнецами.


Я привык к иерархии наследования или владения, а не к циклическим зависимостям.

Я так понимаю, что двунаправленных списков и других моделей ты никогда не встречал :) Ну это скорее твоя беда.

Может и не встречал, но это явно не тот случай. Тут форма связана с сессией и с транзакцией в БД - явно без списков обошлись. Чел просто захотел всю логику хранить в одном месте, но строк кода выходило многовато (несколько тысяч), поэтому накропал с пару десятков классов и интерфейсов - по несколько сотен строк, всё равно тесно их связав. Теперь, чтобы понять, что делают эти сиамские близнецы, я должен держать открытыми эти же пару десятков вкладок, что не укладывается ни на моём экране, ни в моей голове. Даже диаграмма классов выглядит как паутина.

alex445 коренной житель26.07.22 17:17
NEW 26.07.22 17:17 
в ответ alex445 26.07.22 17:13, Последний раз изменено 26.07.22 17:19 (alex445)
Чел просто захотел всю логику хранить в одном месте, но строк кода выходило многовато (несколько тысяч), поэтому накропал с пару десятков классов и интерфейсов - по несколько сотен строк, всё равно тесно их связав.

Ещё посмотрел - он их ещё и по разным проектам разнёс, а проекты - по разным частям приложения (типа апп сервер, веб сайт и прочее). И друг без друга это не работает - т.е. прокты все тоже друг на друга ссылаются.


Это классический махровый монолит, который зачем-то разбили на множество осколков, осколки разнесли по разным углам-доменам, чтобы потом снова собрать их, склеив часть соплями странных наследований, а другую часть "соединив" на расстоянии через интероп, активацию классов динамическим путём и прочую магию.

AlexNek патриот26.07.22 17:58
AlexNek
NEW 26.07.22 17:58 
в ответ alex445 26.07.22 15:05
точно такого же поведения можно добиться, просто используя индекс

ну вот видишь две строки:

obj.Add(key,value);

obj[key] = value;

Что делает каждая из них чисто по внешнему виду?

Murr патриот26.07.22 18:54
Murr
NEW 26.07.22 18:54 
в ответ alex445 26.07.22 10:37

Почему ещё при её создании она не валидируется на длину?

----

А как?

Ну создали стринг... проверили - все Ок.

Ну добавили что-то полученное где-то... строку в процессе 5 раз пересоздали...

Будем проверять? Или ну его нах... в смысле нарушать инкапсуляцию нах...

Срыв покровов патриот26.07.22 19:34
NEW 26.07.22 19:34 
в ответ alex445 26.07.22 13:42
В чём прикол делать приватный словарь, а потом публичные методы доступа к нему GetValue и SetValue

чтобы словарь не обнулить?

P.S. Не знал про доступ по индексу с квадратными скобками. Спасибо.

Программист коренной житель26.07.22 21:14
NEW 26.07.22 21:14 
в ответ alex445 26.07.22 17:13
И то, и то - божественный объект.

Нет. Читай, что такое божественный объект.


Оттого, что вы разобьёте один класс на два, но очень связанных, от божественности вы не избавитесь.

Сильная связь - композиция. Слабая связь - агрегация. Что ты понимаешь под сильной и слабой связью мне не ведомо. Боюсь, что тебе тоже :)


Тут форма связана с сессией и с транзакцией в БД - явно без списков обошлись.

Список - это просто пример модели. Но если ты посмотришь на любую реляционную БД, то увидишь, что таблицы связаны между собой какими-то ключами.

Ну скажем Клиент через ID связан с каким-то Адресом. Т.е. имея Клиента ты всегда можешь получить адрес и имея адрес всегда можешь получить Клиента (или несколько).

Т.е. интерфейсы можно записать так:

public interface ICustomer
{
   int Id { get; }
   string FirstName { get; }
   string LastName { get; }
   IAddress Address { get; }
}

public interface IAddress
{
    string City { get; }
    string Zip { get; }
    string Street { get; }
    string HouseNr {get; }
    IEnumerable<ICustomer> Customers { get; }
}

Такая конструкция вполне имеет право на жизнь. Никакого криминала тут нет.


alex445 коренной житель27.07.22 09:45
NEW 27.07.22 09:45 
в ответ AlexNek 26.07.22 17:58

точно такого же поведения можно добиться, просто используя индекс

ну вот видишь две строки:

obj.Add(key,value);

obj[key] = value;

Что делает каждая из них чисто по внешнему виду?

Вы апеллируете к тому, что программист может не знать особенности работы индекса словаря, а особенности работы его метода Add ему хорошо известны?

alex445 коренной житель27.07.22 09:51
NEW 27.07.22 09:51 
в ответ Murr 26.07.22 18:54

Почему ещё при её создании она не валидируется на длину?

----

А как?

Ну создали стринг... проверили - все Ок.

Ну добавили что-то полученное где-то... строку в процессе 5 раз пересоздали...

Будем проверять? Или ну его нах... в смысле нарушать инкапсуляцию нах...

Ну согласен. Или городить свой класс строк, которые бы имели встроенное ограничение (пусть задаваемое).


Но с этим ладно. А вот как сделать, чтобы к валидирующим значениям (типа макс. длина, границы чисел) можно было легко иметь доступ в любом месте приложения? В том числе в БД. Эти магические числа (string <= 20) в разных частях приложения - явно не то.


Похоже, нужна генерация. Где-то хранить данные по валидации, затем по ним генерировать таблицы БД (подгоняя туда ограничения по длинам, диапазонам и прочему), затем по ним же генерировать атрибуты для классов (которые тоже в свою очередь генерировать). Если без генерации, то минимум для каждой технологии придётся иметь хранилище валидирующих данных. Т.е. написал БД, затем пишешь модель на языке программирования, а валидацию в тех же атрибутах - просто копируешь из данных БД руками.

alex445 коренной житель27.07.22 09:55
NEW 27.07.22 09:55 
в ответ Срыв покровов 26.07.22 19:34, Последний раз изменено 27.07.22 09:57 (alex445)
В чём прикол делать приватный словарь, а потом публичные методы доступа к нему GetValue и SetValue
чтобы словарь не обнулить?
P.S. Не знал про доступ по индексу с квадратными скобками. Спасибо.

Обнулить словарь? Так его можно обнулить и цепочкой вызовов этих методов доступа.


Я максимум что могу предположить - абстрагирование деталей хранения от пользователя. Но как уже писал, судя по реализации - больше похоже на преждевременную оптимизацию.

alex445 коренной житель27.07.22 10:08
NEW 27.07.22 10:08 
в ответ Программист 26.07.22 21:14
Оттого, что вы разобьёте один класс на два, но очень связанных, от божественности вы не избавитесь.

Сильная связь - композиция. Слабая связь - агрегация. Что ты понимаешь под сильной и слабой связью мне не ведомо. Боюсь, что тебе тоже :)

Здесь я имею ввиду не понития компоновки объектов, а то, как тесно они взаимодействуют. Можно сделать "слабую связь" по вашим понятиям (аггрегацию), а затем заставить их очень тесно взаимодействовать. Вот это я и имею ввиду - два класса (уже три), все используют друг друга очень сильно (вызывают друг у друга свойства и методы). Выкинь один - другой становится бессмысленным. А как оно там скомпоновано - дело десятое.

Программист коренной житель27.07.22 10:45
NEW 27.07.22 10:45 
в ответ alex445 27.07.22 10:08
Здесь я имею ввиду не понития компоновки объектов, а то, как тесно они взаимодействуют. Можно сделать "слабую связь" по вашим понятиям (аггрегацию), а затем заставить их очень тесно взаимодействовать. Вот это я и имею ввиду - два класса (уже три), все используют друг друга очень сильно (вызывают друг у друга свойства и методы). Выкинь один - другой становится бессмысленным. А как оно там скомпоновано - дело десятое.

Ккак тесно они взаимодействуют не имеет никакого значения. У тебя в компе процессор и материнская плата взаимодействуют очень тесно, более того, процессор без материнской платы - бессмысленен, материнская плата без процессора тоже не имеет большого смысла. Однако по сути это независимые друг от друга объекты.

И если у тебя в PC процессор можно вынуть из материнской платы и заменить на другой (агрегация) - это слабая связь, то у тебя в смартфоне процессор впаян в материнскую плату (композиция) и это сильная связь.


4 5 6 7 8 9 10 11 12 13 14 все