Обратный инжиниринг: представление словаря C#? - PullRequest
3 голосов
/ 08 апреля 2020

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

Здесь мы go: у пользователя может быть много профилей, каждый из которых привязан к одному и тому же приложению. Профиль определяет права пользователя в приложении: один и тот же пользователь может быть администратором в области app1, в то же время базовый c пользователь app2 ...

Псевдокод выглядит так:

public class User
{
   public string UserId { get; set; }

   // Only store the AppId of application but it could be an IDictionary<Application, UserProfile>
   public IDictionary<string, UserProfile> Profiles { get; set; }
}

public enum UserProfile 
{
   BasicUser,
   Administrator,
}

public class Application
{
   public string AppId { get; set; }
}

Как видите, UserProfile - это просто перечисление, тогда как Application может быть простой строкой, но мне нужен здесь класс.

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

Ответы [ 3 ]

2 голосов
/ 09 апреля 2020

Словари имеют значение!

Сначала я думал как qwerty_so , за исключением того, что:

  • существует квалифицированная ассоциация с UserProfiles: это реализовано с помощью IDictionary, где string используется для определения User.
  • эта ассоциация ориентируется в одном направлении, поскольку вы можете легко go от User до UserProfile, но гораздо труднее go наоборот (вы можете, но вы приходится перебирать все варианты использования).

Таким образом, диаграмма может выглядеть следующим образом:

enter image description here

Некоторые дополнительные замечания об этой диаграмме:

  • Не существует стандарта UML для свойств C#, которые представляют собой смесь между свойством UML и операцией UML (через неявные методы получения и установки). Обычной практикой является использование профиля UML, который определяет стереотип «property». Мой собственный предпочтительный вариант - оставить его в свойствах класса (например, здесь или здесь ), поскольку это semanti c свойства C#. Однако некоторые утверждают, что этот стереотип следует рассматривать как специализацию операции UML (например, здесь и в ответе qwerty), что также является допустимым аргументом, особенно если вы определяете пользовательские методы получения и установки.
  • Будьте осторожны с множественностью в квалифицированной ассоциации, так как это относится к User, квалифицированному со строкой. Таким образом, 0..1 UserProfile предназначен для одной конкретной c комбинации пользователя и строки. Так что в действительности это 0 .. * если бы мы рассматривали неквалифицированное User.

Преобразование модели

Мы должны помнить, что данная реализация может соответствовать различным проектам. Реализация - это то, как вы пишете код, а дизайн - то, как вы видите вещи.

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

Например, вас может не интересовать навигация, и вы можете сосредоточиться на множителях «многие ко многим». связь между неквалифицированными User и UserProfile. При таком подходе строка, использованная в качестве квалификатора, станет свойством класса ассоциации :

enter image description here

Тем не менее помните что это трансформация. Квалифицированная ассоциация и «один ко многим» не одно и то же, и эти две модели не означают одно и то же.

А вот и n-арная ассоциация!

Теперь ключевым вопросом является назначение свойства string в этом классе ассоциаций. Я сильно подозреваю, что это на самом деле id вашего Application (я позволю вам подтвердить в комментариях).

Если это так, у нас будет ассоциация между классом ассоциации и Application. И мы можем удалить строковое свойство из класса ассоциации, потому что тогда оно будет избыточным.

Но ассоциативный класс, который сам связан с каким-то другим классом, показывает, что на самом деле существует n-арная ассоциация (троичный здесь). Итак, мы можем сделать это явно:

enter image description here

Теперь у вас есть n-арная ассоциация. Вы могли бы даже иметь класс ассоциации за ним, если бы были дополнительные свойства для связи с каждым триплетом (User, Application, UserProfile).

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

Заключение / советы

Лично мне трудно работать с n-арными ассоциациями, и я предпочитаю разбивать их на наборы классов и бинарных ассоциаций (и классов ассоциаций, когда это необходимо): это позволяет устранить много неоднозначности и дает более жесткий контроль. Я могу только рекомендовать вам такой же подход.

Рассмотрим также вашу реализацию: если реализация представляет ваш взгляд на мир, используйте квалифицированную ассоциацию, потому что это UML-эквивалент словаря.

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

2 голосов
/ 14 апреля 2020

Ваше C# свойство User::Profiles реализует класс ассоциации "многие ко многим" между User и Application, имеющий свойство UML, такое как role: RoleEL, где я заменил имя вашего перечисления "UserProfile" на "RoleEL msgstr "для лучшей читаемости (обратите внимание, что" EL "означает" литерал перечисления "). Это показано на следующей диаграмме классов:

enter image description here

Я думаю, что эта модель проектирования проще и естественнее, чем модели, предложенные @qwerty_so и @Christophe ,

Обратите внимание, что модель qwerty_so не является (логической) моделью проектирования, а скорее моделью реализации, так как она не отображает отношения между User и Application, а скорее хранит ее в код свойства profiles. Кроме того, он излишне дублирует свойство UML (используя запутанное ключевое слово стереотипа «свойство»).

2 голосов
/ 08 апреля 2020

Я не вижу никакой n-арной ассоциации в вашем коде.

То, что вы набросали, выглядит так:

enter image description here

Application не связан ни с чем, поэтому он является сиротой.

Свойства могут быть представлены по-разному и являются спецификацией языка c. Вышеуказанное будет использовано для C#

...