Я столкнулся с некоторым кодом (C #, если это имеет значение), который имеет классы, которые имеют одинаковые имена, но различаются по своим пространствам имен. Все они, как правило, представляют одну и ту же логическую вещь, но часто являются разными «взглядами» на один и тот же объект. Разные пространства имен иногда являются частью одного и того же решения и даже одной и той же библиотеки DLL.
У меня есть свои мысли, но я не мог найти ничего определенного в этой практике, чтобы считаться умным использованием доступных инструментов или схем, которых следует избегать.
Этот вопрос о наименовании smurf касается этого, но с другой стороны. Для устранения неоднозначности имен, вероятно, потребуется произвольный и распространенный префикс, который этот вопрос хотел бы устранить.
Каковы основные принципы этой практики?
FooAdapter
,FooViewer
,FooCalculator
и т.д. , но , конечно , не назвал то же самое. Однако, без дополнительной информации о конкретных классах, о которых вы говорите, трудно дать ответ.Employee
в качестве примера. Есть сотрудник, который предназначен для других сотрудников, один для HR, один для внешнего воздействия. Все они называются «работники», и у них всех есть различные помощники (EmployeeRepository, EmployeeView и т. Д.). Все они находятся в одной и той же dll, и хотя они имеют некоторые общие свойства (имя, должность), все они различаются (номер телефона, зарплата).Employee
несколько раз, звучит так, будто вам нужна модель с объединением всех атрибутов и включением атрибутаtype
илиdepartment
. В противном случае происходит ненужное дублирование кода.Ответы:
Я постараюсь дать ответ против такого использования, после того, как увидел и работал над этим в одном из моих проектов.
Читаемость кода
Прежде всего, учтите, что читабельность кода важна, и эта практика противоречит этому. Кто-то читает кусок кода, и давайте просто скажем, что у него есть функция
doSomething(Employee e)
. Это больше не доступно для чтения, потому что из-за 10 различныхEmployee
классов, существующих в разных пакетах, вам придется сначала прибегнуть к объявлению импорта, чтобы выяснить, что вы на самом деле делаете.Это, однако, высокоуровневое представление, и у нас часто бывают, казалось бы, случайные конфликты имен, о которых никто не заботится и даже не находит, потому что значение может быть получено из оставшегося кода и того, в каком пакете вы находитесь. Так что можно даже поспорить что на местном уровне проблем нет, потому что, конечно, если вы видите
Employee
внутриhr
пакета, вы должны знать, что мы говорим о кадровом представлении сотрудника.Вещи распадаются, как только вы покидаете эти пакеты. Если вы работаете в другом модуле / пакете / и т. Д. И вам необходимо работать с сотрудником, вы уже жертвуете удобочитаемостью, если не полностью определяете его тип. Кроме того, наличие 10 различных
Employee
классов означает, что автозаполнение IDE больше не будет работать, и вам придется вручную выбирать тип сотрудника.Дублирование кода
Из-за того, что каждый из этих классов связан друг с другом, ваш код будет ухудшаться из-за большого количества дубликатов. В большинстве случаев у вас будет что-то вроде имени сотрудника или некоторого идентификационного номера, который должен реализовать каждый из классов. Несмотря на то, что каждый класс добавляет свое собственное видение, если они не разделяют базовые данные о сотрудниках, вы получите огромную массу бесполезного, но дорогостоящего кода.
Сложность кода
Что может быть таким сложным, спросите вы? В конце концов, каждый из классов может держать это так просто, как он хочет. Что действительно становится проблемой, так это то, как вы распространяете изменения. В достаточно многофункциональном программном обеспечении вы можете изменять данные о сотрудниках - и вы хотите отразить это повсюду. Скажите, что одна женщина только что вышла замуж, и вы должны переименовать ее
X
вY
благодаря этому. Достаточно сложно сделать это правильно повсюду, но еще сложнее, когда у вас есть все эти разные классы. В зависимости от вашего другого выбора дизайна, это может легко означать, что каждый из классов должен реализовать свой собственный тип слушателя или что-то подобное, чтобы получать уведомления об изменениях - что в основном означает фактор, применяемый к числу классов, с которыми вам приходится иметь дело , И, конечно, больше дублирования кода и меньшая читаемость кода. Подобные факторы могут не учитываться при анализе сложности, но они, несомненно, раздражают применительно к размеру вашей кодовой базы.Код связи
Помимо вышеупомянутых проблем со сложностью кода, которые также связаны с выбором дизайна, вы также снижаете четкость проектирования на более высоком уровне и теряете способность правильно общаться с экспертами в предметной области. Когда вы обсуждаете архитектуру, дизайн или требования, вы больше не можете делать простые заявления вроде
given an employee, you can do ...
. Разработчик больше не будет знать, что наemployee
самом деле означает в этот момент. Хотя специалист по домену это будет знать конечно. Все мы делаем. вроде. Но с точки зрения программного обеспечения это не так легко общаться больше.Как избавиться от проблемы
Узнав об этом, и если ваша команда согласится с тем, что это достаточно большая проблема для ее решения, вам придется выработать способ ее решения. Как правило, вы не можете попросить своего менеджера дать всей команде отпуск на неделю, чтобы они могли вынести мусор. По сути, вам придется найти способ частично исключить эти классы, по одному за раз. Самая важная часть в этом - решить - со всей командой - что на
Employee
самом деле. Вы не интегрировать все отдельные атрибуты в один крестной работника. Подумайте больше о главном сотруднике и, самое главное, решите, гдеEmployee
будет находиться этот класс.Если вы выполняете проверку кода, то особенно легко убедиться, что проблема, по крайней мере, больше не будет расти, т.е. остановите всех прямо на своем пути, когда они захотят добавить еще одну
Employee
. Также позаботьтесь о том, чтобы новые подсистемы соответствовали согласованнымEmployee
и не имели доступа к старым версиям.В зависимости от вашего языка программирования, вы также можете пометить классы, которые в конечном итоге будут исключены, что-то вроде того,
@Deprecated
чтобы помочь вашей команде сразу понять, что они работают с чем-то, что должно быть изменено.Что касается избавления от устаревших классов сотрудников, вы можете решить для каждого отдельного случая, как его лучше устранить, или просто договориться об общей схеме. Вы можете прикрепить имя класса и обернуть его вокруг реального сотрудника, вы можете использовать шаблоны (на ум приходят декоратор или адаптер), или, или или.
Короче говоря: эта «практика» технически обоснована, но она полна скрытых затрат, которые произойдут только в будущем. Хотя вы, возможно, и не сможете сразу избавиться от проблемы, вы можете немедленно начать с сдерживания ее вредных последствий.
источник
Scala Collection Framework является хорошим примером этого. Существуют изменяемые и неизменные коллекции, а также последовательные и параллельные (и в будущем, возможно, также распространяемые) коллекции. Итак, есть, например, четыре
Map
черты:плюс три
ParMap
с:Еще интереснее
Итак,
ParMap
расширяетсяParMap
расширяетсяMap
иMap
расширяетсяMap
расширяетсяMap
.Но давайте посмотрим правде в глаза: как еще вы бы их назвали? Это имеет смысл. Вот для чего нужны пространства имен!
источник
Это действительно интересный вопрос, в котором оба принципиально противоположных ответа верны. Вот реальный пример этой дискуссии, которую мы ведем по моему проекту.
Я думаю, что на данный момент есть два очень важных соображения, которые заставили бы вас пойти в одном или другом направлении, опираясь на два ответа @Jorg и @Frank:
hr.Employee
но в то же время нужно смотреть через разрешения черезsecurity.Employee
, это очень быстро раздражает.Map
классы реализуют один и тот же интерфейс или являются подклассами друг друга. В этом случае двусмысленность или «путаницу» можно назвать хорошей вещью, потому что пользователь по праву может относиться ко всем реализациям класса или интерфейса одинаково ... что является точкой интерфейсов и подклассов.источник