Идентичные имена классов в разных пространствах имен

У меня есть два разных пространства имен с множеством классов с одинаковыми именами. Я считаю, что некоторый код облегчит понимание:

namespace Print.Pdl.PostScript.Operators
{
    public abstract class BaseOperator : IOperator
    {
         // ...
    }
}

namespace Print.Pdl.Pcl6.Operators
{
    public abstract class BaseOperator : IOperator
    {
         // ...
    }
}

Базовая реализация одинакова, поскольку PostScript и PCL имеют схожие конструкции. Таким образом, оба пространства имен имеют одинаковые имена для нескольких классов.

Я склоняюсь к следующему...

namespace Print.Pdl.PostScript.Operators
{
    public abstract class BasePsOperator : IPsOperator
    {
         // ...
    }
}

namespace Print.Pdl.Pcl6.Operators
{
    public abstract class BasePclOperator : IPclOperator
    {
         // ...
    }
}

... но, ИМХО, это как бы противоречит цели, так как в идентификации есть избыточность. Зачем мне префикс/изменение имен классов, если пространство имен уже создает логический барьер?

Итак, что вы думаете? Должен ли я сохранить идентичные имена, поскольку они находятся в разных пространствах имен, или я должен префикс/изменить имена классов, чтобы упростить идентификацию источника и избежать конфликтов, если кто-то захочет использовать оба пространства имен вместе?

Спасибо!


person Ricardo Nolde    schedule 19.04.2011    source источник
comment
На этот вопрос действительно есть ответ? Или это дело вкуса?   -  person Ricardo Nolde    schedule 25.04.2011


Ответы (6)


Нольде,

Я не думаю, что вы должны жертвовать архитектурой в пользу удобочитаемости. Я считаю, что более интуитивно понятно, если вы сохраняете те же имена классов, поскольку это упрощает переход с PCL на PostScript и наоборот.

Если вам нужно использовать оба класса в одном файле кода, создайте псевдоним для пространства имен. Будет очень ясно читать:

using Pcl = Print.Pdl.Pcl6.Operators;
using PostScript = Print.Pdl.PostScript.Operators;
...
// use PCL
Pcl.BaseOperator.DoSomething();
// Use PostScript
PostScript.BaseOperator.DoSomething();

Спасибо, Лучано Баргманн.

person Luciano Bargmann    schedule 19.04.2011
comment
Псевдонимы мне тоже нравятся. Может быть, разные разработчики будут использовать разные псевдонимы для этих пространств имен? да. Но я не вижу в этом серьезной проблемы с читабельностью. Что касается использования обоих пространств имен в одном и том же файле, это также не должно быть проблемой, так как это приведет к ошибке, говорящей о том, что BaseOperator неоднозначен. - person diogoriba; 20.04.2011
comment
Я согласен, но действительно ли это проблема архитектуры? Ничто не изменится в том, как работают классы или как они будут связаны с другими классами. Меняется только название. Должен ли я действительно беспокоиться об этом? - person Ricardo Nolde; 26.04.2011

Имхо сложный вопрос. Чтобы правильно ответить на него, вам нужно знать, как часто люди могут использовать оба пространства имен одновременно и как их раздражает необходимость добавлять ко всему пространству имен префикс.

Лично я склоняюсь к "разным именам". Я думаю о пространствах имен как о механизме ограничения набора имен, видимых в коде, и о защите от маловероятного случая, когда имена конфликтуют даже в этом сокращенном наборе. Так что сохранение столкновения «маловероятно» важно. Поэтому я лично не стал бы специально создавать коллизию.

Тем более, что в вашем случае разница так мала: BaseOperator лишь чуть короче, чем BasePsOperator.

person Roman Starkov    schedule 19.04.2011
comment
Это действительно зависит от того, как часто классы в пространствах имен будут создаваться в одном и том же классе. Если это случается нечасто, то можно дать им одно и то же имя. Кроме того, помните, что вы не совсем застряли в своем решении: Visual Studio предлагает несколько достойных инструментов рефакторинга, которые помогут вам переименовать ваши классы, если вы передумаете позже. - person Katie Kilian; 19.04.2011
comment
Но с возможностью создания псевдонима пространства имен в C#, не должен ли я предоставить программистам возможность использовать using Print.Pdl.PostScript.Operators = PsOps вместо изменения имен? И помните, что это всего лишь один пример: существует несколько классов с одинаковыми именами. - person Ricardo Nolde; 19.04.2011
comment
@Charlie Ну, почти - это зависит от того, как часто вы используете оба пространства имен одновременно. Даже если вы только когда-либо создаете экземпляр Ps.Operator, использование пространств имен Ps и Pcl заставит вас записать Operator с пространством имен. - person Roman Starkov; 19.04.2011
comment
@ Рикардо да, но это делает код менее читаемым. Первый программист называет его PsOps, второй программист называет его Ps. Таким образом, файл 1 имеет PsOps.Operator, а файл 2 имеет Ps.Operator. Это плохо для читабельности. - person Roman Starkov; 19.04.2011
comment
@romkyns Абсолютно. Я слишком конкретно выразился. - person Katie Kilian; 19.04.2011
comment
@Charlie Чарли, я определенно согласен с вашим комментарием по рефакторингу, хотя, конечно, вы теряете эту возможность, если когда-либо отправляете свой API третьим лицам :) - person Roman Starkov; 19.04.2011
comment
@romkyns Собственно говоря, это мой случай. На самом деле это не третьи лица, а большая зарубежная команда в огромном проекте. Рефакторинг в этом случае требует значительных усилий. - person Ricardo Nolde; 19.04.2011
comment
+1; если это разные вещи, идентифицируйте их с отличительными именами. - person Tim Barrass; 19.04.2011
comment
@Tim На самом деле, это одно и то же, но в разных контекстах. :) - person Ricardo Nolde; 20.04.2011
comment
Поясню: они одинаковы по отношению к PDL, на который ссылаются, но отличаются друг от друга. - person Ricardo Nolde; 20.04.2011

Разные пространства имен — это просто... Разные, имя, пространства поэтому вам вообще не стоит беспокоиться (как правило) о дублировании имена за пределами пространства имен.

Тем не менее, вы должны осознавать использование. например вы создаете многоуровневое приложение со многими разными слоями (в разных пространствах имен), вы не хотели бы дублировать имена классов, которые могут быть общими для разных слоев.

Если вы считаете разумным использовать повторяющиеся имена между пространствами имен, вы всегда можете использовать удобные операторы using для переименования в потребляющих классах, например.

у вас есть два класса пользователей:

Data.Entities.User;
App.Core.User;

И хочу использовать их в одном и том же месте...

Вы можете использовать простой оператор using, такой как

using HttpUser = App.Core.User; 

Псевдоним одного из них и, таким образом, избегая полной квалификации и избегая путаницы.

person MemeDeveloper    schedule 18.10.2012

Если между двумя предложенными базовыми классами нет функциональной или интерфейсной разницы, то, возможно, создайте другое общее пространство имен с BaseOperator в нем - и просто определите его один раз.

person Tim Barrass    schedule 19.04.2011
comment
Это хороший совет, но здесь это не так — эти классы семантически похожи, поскольку PostScript и PCL6 имеют схожую структуру, но они ведут себя достаточно по-разному, чтобы сделать единый класс нецелесообразным. - person Ricardo Nolde; 19.04.2011

Я считаю, что вы должны использовать схему именования, отражающую специализацию.

Я имею в виду, что вам не нужно думать о том, является ли это префиксом, суффиксом или любым другим. Просто напишите имена, которые могут четко идентифицировать классы.

Честно говоря, я считаю, что пространство имен не заменит правильную схему именования классов, потому что пространства имен — это организационная вещь, а классы — часть того, что делает ваша программа.

Итак, в конце концов, я бы выбрал второй вариант: специализированное именование пространств имен и классов.

person Matías Fidemraizer    schedule 19.04.2011

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

person tster    schedule 19.04.2011