【问题标题】:Reverse engineering: representation of a C# Dictionary?逆向工程:C# 字典的表示?
【发布时间】:2020-04-07 21:27:46
【问题描述】:

我已经编写了我的代码,但就我个人而言,我想知道如何对其进行建模。

我们开始吧:一个用户可以拥有多个配置文件,每个配置文件都与一个且唯一的应用程序相关联。配置文件定义了应用程序内的用户权限:同一用户可以是 app1 范围内的管理员,同时是 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 个实体?我认为类关联不是一个好的选择,因为它没有任何属性。但我不知道还有什么可能。

【问题讨论】:

    标签: uml class-diagram


    【解决方案1】:

    我在您的代码中没有看到任何 n 元关联。

    你的草图是这样的:

    Application 与任何东西都没有关联,因此它是一个孤儿。

    属性可以用不同的方式表示,并且是特定于语言的。以上将用于 C#

    【讨论】:

    • 感谢您的努力。如果profiles&lt;Application, UserProfile&gt; 而不是&lt;string, UserProfile&gt; 的字典,这两个类将如何关联?
    • 在这种情况下,您将依赖于 Application,就像使用枚举一样。
    • 您的模型没有将UserApplication 之间的关系捕获为关联(类)。此外,在 C# 实现模型中复制类矩形中的属性是一种非常丑陋/嘈杂的方法。这可以使用 > 属性构造型以更好的方式表达,参见stackoverflow.com/questions/28139621/…
    • @GerdWagner 你可能是对的。在回答此类问题时,我的意图不是给出一个完整的模型(如果没有广泛的讨论,这是不可能的)。更多的是我试图指出某个方向。看看克里斯托夫的回答:老实说,我懒得详细说明。我只能猜测这是被要求进行某种考试的,而 OP 正在编写这些考试。帕累托规则。
    【解决方案2】:

    字典很重要!

    一开始我的想法是qwerty_so,除了:

    • 有一个qualified associationUserProfiles:它通过IDictionary 实现,其中string 用于限定User
    • 此关联可在一个方向导航,因为您可以轻松地从 User 转到 UserProfile,但要反过来则要困难得多(可以,但您必须遍历所有用途)。

    所以图表可能如下所示:

    关于此图的一些补充说明:

    • 对于 C# 属性没有 UML 标准,它是 UML 属性和 UML 操作的混合体(通过隐式 getter 和 setter)。通常的做法是使用定义原型«property» 的UML 配置文件。我自己的首选选项是将其保留在类的属性中(例如 herehere),因为这是 C# 属性的语义。然而,有些人认为这种刻板印象应该被视为 UML 操作的特化(如here 和 qwerty 的答案),这也是一个有效的论点,尤其是在您定义自定义 getter 和 setter 时。
    • 注意限定关联中的多重性,因为它适用于使用字符串限定的User。所以 0..1 UserProfile 是针对用户和字符串的一种特定组合。所以如果我们考虑不合格的User,它实际上是 0..*。

    模型转换

    我们必须记住,给定的实现可能对应于不同的设计。实现是你编写代码的方式,设计是你看待事物的方式。

    因此,我们可以转换第一个逆向工程模型以匹配您的思维模型。只有您才能说出您希望如何看待导致您实现当前实施的事物。

    例如,您可能对可导航性不那么感兴趣,您可以将重点放在不合格的UserUserProfile 之间的多对多关联上。使用这种方法,用作限定符的字符串将成为association class 的属性:

    但请注意,这是一种转变。合格的关联和一对多不是一回事,这两个模型并不意味着完全一样的东西。

    n-ary 关联来了!

    现在的关键问题是这个关联类中字符串属性的用途。我强烈怀疑它实际上是您的Applicationid(我让您在 cmets 中确认)。

    如果是这样,我们将在关联类和Application 之间建立关联。我们可以从关联类中删除字符串属性,因为它会是多余的。

    但一个关联类本身与某个其他类相关联,表明实际上存在一个n-ary associaton(此处为三元)。所以,我们可以明确表示:

    现在你有了一个 n 元关联。如果每个三元组(用户、应用程序、用户配置文件)有额外的属性关联,你甚至可以在它后面有一个关联类。

    但请注意,此图不太精确。例如,在 n 元关联中指示可导航性约束更加困难。而且它不再完全对应于您的实现:此模型表明您可以从应用程序开始找到用户,而在您的实现中则更加困难。

    结论/建议

    就个人而言,我发现 n 元关联很难使用,我更喜欢将它们分解为一组类和二元关联(必要时还包括关联类):这可以消除很多歧义并提供更严格的控制。我只能向您推荐相同的方法。

    还要考虑您的实现:如果该实现代表您对世界的看法,则使用限定关联,因为它是 UML 等价于字典。

    但是,如果三元关联是您的世界观,您可能迟早必须审查当前的实施。可能您会提取配置文件以创建自己的类。

    【讨论】:

    • 我喜欢你的 n-ary 关联,这很像我在提问时想象的设计。但是您指出它与我的实现并不完全对应,我认为您是对的!可导航性是关键。为了匹配这个图表,我的应用程序类中也应该有一个用户/配置文件字典。由于情况并非如此,因此合格的协会似乎是最佳人选。谢谢。
    • 是的,在您的第一张图中,:stringAppId 相同。我编辑了我的问题以改进 ID 的命名。
    • 您的模型没有将UserApplication 之间的关系捕获为关联(类)。另请注意,“世界观”对应于(逻辑)设计模型,而不是使用地图/字典来实现多值属性的实现选择。
    • @GerdWagner 在 n 元关联中,用户始终与应用程序以及用户配置文件相关联。这意味着您可以找到一个用户的应用程序或一个应用程序的用户。在 n 元关联后面,您也可能有一个关联类,就像在二元关联后面一样。我没有展示它,因为当前代码不需要它。事实上,如果每个应用程序(但代码中没有证据)独立于配置文件的属性(例如用户偏好),我们可以考虑在用户和应用程序之间建立额外的二进制关联。
    • @GerdWagner 我完全同意你的第二句话。事实上,我使用了一种逐步的方法让 OP 有机会在实现模型和设计模型之间进行选择(尽管如此,假设第二种会更有用)。
    【解决方案3】:

    您的 C# 属性 User::Profiles 实现了 UserApplication 之间的多对多关联类,该类具有像 role: RoleEL 这样的 UML 属性,其中我已将您的枚举名称“UserProfile”替换为“RoleEL”更好的可读性(注意“EL”代表“枚举文字”)。这显示在下面的类图中:

    我认为这种设计模型比@qwerty_so 和@Christophe 建议的模型更简单、更自然。

    请注意,qwerty_so 的模型不是(逻辑)设计模型,而是实现模型,因为它不显示 UserApplication 之间的关系,而是将其隐藏在代码中profiles 财产。此外,它不必要地复制了 UML 属性(使用令人困惑的原型关键字 «property»)。

    【讨论】:

    • 我也喜欢这个。现在我不知道在你的建议和@Christophe 的第一个建议之间选择哪一个,保留切换UserProfileApplication
    • @paradise:请注意,@Christophe 的模型不能正确地将UserApplication 之间的关系建模为关联(类)。
    • @paradise: 另请注意,我的模型允许通过添加更多属性(例如 使用时间)来扩展用户应用配置文件。
    • 是的,这也是一个不错的模型。我可能会从那里开始进行正向工程。在我的回答中,我很想展示这样的第二步。但我没有,因为问题是关于逆向工程的,我想坚持这个思考过程。此外,在用户管理领域,应用程序角色通常看起来比仅一个枚举更复杂(例如,动态创建,与功能或数据约束相关联)。该模型不会以与用户无关的实体相同的方式承认角色的存在。但是 +1 因为它是一个有效的替代品
    猜你喜欢
    • 2012-05-01
    • 2010-10-12
    • 2015-08-15
    • 2011-01-17
    • 2012-08-26
    • 2012-01-08
    • 2012-05-31
    • 2011-06-07
    • 2016-09-27
    相关资源
    最近更新 更多