当前位置: 首页 > 知识库问答 >
问题:

逆向工程:C# 字典的表示形式?

许俊风
2023-03-14

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

我们开始吧:一个用户可以有许多配置文件,每一个都与唯一的应用程序相关联。配置文件定义了用户在应用程序中的权限:同一用户可以是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 只是一个枚举,而应用程序可以是一个简单的字符串,但我在这里需要一个类。

我如何在类图上表示这三个实体?我认为类关联不是一个好的选择,因为它没有任何属性。但是我不知道还有什么可能。

共有3个答案

郏兴贤
2023-03-14

您的C#属性User::ProfilesUserApplication之间实现了一个多对多的关联类,该类具有一个UML属性,如role:RoleEL,为了更好的可读性,我将您的枚举名称“UserProfile”替换为“RoleEL”(注意,“EL”代表“枚举文字”)。如下图所示:

我觉得这个设计模式比@qwerty_so和@Christophe建议的模式更简单自然。

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

袁博
2023-03-14

起初我像qwerty_so一样思考,除了:

    < li >有一个与< code>UserProfiles的限定关联:它通过< code>IDictionary实现,其中< code >字符串用于限定< code >用户。 < li >这种关联在一个方向上是可导航的,因为您可以很容易地从< code>User转到< code>UserProfile,但反过来就困难多了(您可以,但必须遍历所有的使用)。

因此,图表可能看起来像:

关于此图的一些附加说明:

    < Li > C #属性没有UML标准,它是UML属性和UML操作(通过隐式getter和setter)的混合。通常的做法是使用一个定义原型< code >属性的UML概要文件。我自己的首选是将它保存在类的属性中(比如这里或这里),因为这是C#属性的语义。然而,有些人认为这种构造型应该被认为是UML操作的专门化(就像这里和qwerty的回答),这也是一个有效的论点,特别是如果你定义了定制的getters和setters。 < li >注意限定关联中的多重性,因为它适用于用字符串限定的< code>User。所以0..1 UserProfile用于用户和字符串的特定组合。所以它在现实中是0..*如果我们认为< code >用户不合格。

我们必须记住,一个给定的实现可以对应不同的设计。实现是你如何写代码,设计是你如何看待事物。

所以我们可以转换这个第一个逆向工程模型来匹配你的思维模型。只有你能说出你想如何看到导致你当前实现的事情。

例如,您可能对可导航性不太感兴趣,您可以将重点放在非限定用户用户配置文件之间的多对多关联上。使用此方法,用作限定符的字符串将成为关联类的属性:

然而要意识到这是一种转变。合格关联和一对多不是一回事,两种模式的含义也不完全相同。

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

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

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

现在,您有一个 n 元关联。您甚至可以在其后面有一个关联类,如果有其他属性要与每个三元组(用户、应用程序、用户配置文件)相关联。

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

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

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

但是,如果三元关联是你的世界观,你可能迟早要审查你当前的实现。也许你会提取配置文件来创建一个自己的类。

邹海超
2023-03-14

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

你画的是这样的:

应用程序与任何事物都没有关联,因此它是孤立的。

属性可以用不同的方式表示,并且是语言规范的。上述内容将用于C#

 类似资料:
  • 逆向工程 是模型其中一个主要功能。这功能让你加载现有的数据库结构以创建新的图表。它支持导入 MySQL、 PostgreSQL、Oracle、SQLite、SQL Server 或 MariaDB 数据库、模式、表或视图。 Navicat 提供一个步骤的向导让你完成任务: 选择 工具 -> 从数据库导入。 选择连接。 选择你要导入的数据库、模式或表。 点击 开始。 你也可以简单地在 Navicat

  • 逆向工程是模型的其中一个主要功能。这功能让你加载现有的数据库结构以创建新的图表。它支持导入数据库、模式、表或视图。 Navicat 提供一个向导,一步一步指导你完成任务: 选择“文件”->“从数据库导入”。 选择一个连接。 选择你要导入的数据库、模式、表或视图。 点击“开始”。 你也可以简单地在 Navicat 主窗口使用逆向工程创建一个新模型。右击一个已打开的数据库或模式、表或视图并在弹出式菜单

  • 逆向工程是模型的其中一个主要功能。这功能让你加载现有的数据库结构以创建新的图表。它支持导入数据库、模式、表或视图。 Navicat 提供一个向导,一步一步指导你完成任务: 选择“文件”->“从数据库导入”。 选择一个连接。 选择你要导入的数据库、模式、表或视图。 点击“开始”。 你也可以简单地在 Navicat 主窗口使用逆向工程创建一个新模型。按住 Control 键并点按一个已打开的数据库或模

  • 逆向工程是模型的其中一个主要功能。这功能让你加载现有的数据库结构以创建新的图表。它支持导入数据库、模式、表或视图。 Navicat 提供一个向导,一步一步指导你完成任务: 选择“文件”->“从数据库导入”。 选择一个连接。 选择你要导入的数据库、模式、表或视图。 点击“开始”。 你也可以简单地在 Navicat 主窗口使用逆向工程创建一个新模型。右击一个已打开的数据库或模式、表或视图并在弹出式菜单

  • 主要内容:1. 下载jar包,2. 创建数据表,3. 创建项目Mybatis 提供了一个逆向工程工具,该工具可以根据数据表自动生成针对单表的 po 类、mapper 映射文件和 mapper 接口。大大缩减了开发时间,可以让开发人员将更多的精力放在繁杂的业务逻辑上。 之所以强调单表两个字,是因为 MyBatis 逆向工程生成的 Mapper 中的操作都是针对单表的。在大型项目中,很少有复杂的多表关联查询,所以该工具作用还是很大的。 1. 下载jar包 jar

  • 有没有其他的方法可以让反编译的代码变得不可读? (请不要评论或回答,无论我做什么,CIA总是能够完全逆转我的应用程序。显然,我已经超过了使用Proguard等)。