德米特混乱法则

2023-11-22

我希望有人能帮我解释一下德墨忒耳定律。如果我有一个类,我假设它是一个聚合根,并且其中有一个子类的集合,通过聚合根访问这些子类来更新它们的属性是否非法?

e.g.

public class Company
{
    // company has a number of employees
    public List<Employee> Employees {get; set;}
}

public class Employee
{
    // each employee has a lastname
    public int Id {get; set;}
    public string LastName {get; set;}
    // other properties of employee
}

假设我有一个客户首先要访问 Company 类,那么它是否会违反类似的 Demeter 法则。

Employee e = aCompany.Employees.Where(e => e.Id == 1).Single();
e.LastName = "MarriedName";

或者这应该始终委托给公司

public class Company
{
    public UpdateEmployeeLastName(int employeeId, string newName)
    {
        Employee e = Employees.Where(e => e.Id == employeeId).Single();
        e.LastName = newName;
    }
}

在客户端

aCompany.UpdateEmployeeLastName(1, "Marriedname");

第二个似乎更好,但是客户端必须知道它想要更新的 Employee 的 id 有什么问题吗?

当您有许多嵌套聚合时,这似乎会开始变得复杂。

Thanks


你的第二个选择就是德米特法则的目标。

由于德米特定律基本上规定“只谈论你所知道的”……无论第一个场景中的“客户”是什么,实际上根本不了解员工。它知道一个Company..但不是关于复杂性Company内部结构。

委托给Company让您可以灵活地更改员工的更新方式,而无需从客户端更改此功能的每个特定实例。如果有一天你决定只Active员工可以更改姓名,那么您必须将选项一的每个实例更新为:

Employee e = aCompany.Employees.Where(e => e.Id == 1 && e.IsActive).Single();
//                                                        ^^^^ active flag
e.LastName = "MarriedName";

把它包起来Company使得将来处理这个问题变得更好(无论是否尝试遵循德米特法则)。

第二个似乎更好,但是客户端必须知道它想要更新的 Employee 的 id 有什么问题吗?

你的两个例子都知道员工的ID..所以我不确定你的意思。通过聚合传递信息时,使用代码了解 ID 是很常见的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

德米特混乱法则 的相关文章

  • 为什么 std::vector 可以处理类定义中的不完整类型?

    出现了以下问题 C 标准似乎说 std vector需要一个完整的类型才能工作 看https en cppreference com w cpp container vector https en cppreference com w cp
  • SOAP Web 服务:多台服务器,一个接口

    我有一个场景 需要任意数量的服务器来提供相同的 SOAP Web 服务 我想生成一组代理类 并能够为它们提供一个位置 以便在运行时将它们指向不同的服务器 不幸的是 看起来好像wsdl port节点 子节点wsdl service 要求对特定
  • CMake(Ninja 后端)使用 /MT 编译

    我有一个类似的问题CMake 使用 MT 而不是 MD 进行编译 https stackoverflow com questions 14172856 cmake compile with mt instead of md但有一些差异 我正
  • 获取列表框中视图中的项目

    我有一个 ListBox 其属性 VirtualizingStackPanel VirtualizationMode 设置为 回收 我正在绑定一个自定义集合 实现IList and IList
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • 大量互斥体对性能的影响

    假设我有一个包含 1 000 000 个元素的数组 以及多个工作线程 每个线程都操作该数组中的数据 工作线程可能会使用新数据更新已填充的元素 但每个操作仅限于单个数组元素 并且独立于任何其他元素的值 使用单个互斥锁来保护整个数组显然会导致高
  • DateTime.ParseExact - 为什么 yy 变成 2015 而不是 1915

    为什么 NET 假定以下年份是 2015 年 而不是 1915 年 var d DateTime ParseExact 20 11 15 dd MM yy new CultureInfo en GB 我想 它会尝试接近 但其背后是否有合理的
  • 将 AutomationID 与 ListView 结合使用

    我正在尝试将 AutomationId 附加到列表视图中的项目 理想情况下 将项目名称绑定到显示的项目
  • 运行实体框架自定义工具,它有什么作用?

    在 Visual Studio 中 当使用实体框架并为 tt 和 Context tt 文件应用运行自定义工具时 它是什么以及它有什么作用 为什么它解决数据库同步问题 有时 为什么我应该在运行 tt 之前运行它 Context tt 它被称
  • 为什么这个位图图像在加载后会改变大小?

    快速提问 我有这个1000 1000位图图像 我使用这个例程来加载它 private BitmapSource initialBitmap new BitmapImage new Uri C Users Desktop Original b
  • MPI - 发送和接收列

    我需要从一个进程发送矩阵列并从另一个进程接收它 我尝试运行以下程序 但得到了一个奇怪的结果 至少我这么认为 仅复制矩阵的第一个元素 某些矩阵元素会发生意外变化 include
  • C++网络序列化[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一种将 C 数据包序列化为网络流的解决方案 我在这里看到很多帖子提到人们 ACE 谷歌协议缓
  • 具有多个父项的 Qt 树模型

    我想构建一棵树 其中一个元素可以引用另一个元素 我想要构建的树是 像这样的东西 A B C D E F P this is a pointer to C D first child of C E second child of C I fo
  • C# 多维数组解析

    我有一个多维数组 内容在调试器中看起来像这样 数组设置为 String s new String 6 4 A B Yes C A B Yes C A B No C A B Yes C A B Yes C A B Yes C A B No C
  • 尝试后终于没有被调用

    由于某种原因 在我的控制台应用程序中 我无法运行我的finally 块 我编写这段代码是为了测试finally块是如何工作的 所以它非常简单 static void Main int i 0 try int j 1 i Generate a
  • 如何配置 qt Creator 以显示 C++ 代码而不是反汇编程序?

    昨天我做了很多事情 比如更新 GCC Clang 和重新安装 Qt Creator 今天 在逐步调试我的代码时 调试器显示的是反汇编代码 而不是我编写的 C 代码 紧迫F10 or F11 调试器正在进入汇编代码而不是 cpp nor h我
  • java有类似C#的属性吗? [复制]

    这个问题在这里已经有答案了 C 属性 我的意思是 get 和 set 方法 是一个非常有用的功能 java 也有类似 C 的属性吗 我的意思是我们如何在 java 中实现类似以下 C 代码的内容 public string Name get
  • 将同步 zip 操作转换为异步

    我们有一个现有的库 其中一些方法需要转换为异步方法 但是我不确定如何使用以下方法执行此操作 错误处理已被删除 该方法的目的是压缩文件并将其保存到磁盘 请注意 zip 类不公开任何异步方法 public static bool ZipAndS
  • NHibernate:无状态会话错误消息无法获取代理

    我正在使用 nHibernate 无状态会话来获取对象 更新一个属性并将对象保存回数据库 我不断收到错误消息 无状态会话无法获取代理 我在其他地方有类似的代码 所以我不明白为什么这不起作用 有谁知道问题可能是什么 我正在尝试更新Screen
  • 如何使用 Microsoft Graph API 更新 MailboxSettings

    我想从不同的日历更新邮箱设置 如何构建可以通过 Microsoft Graph 更新 MailboxSetting 的请求 这是我的代码示例 但有例外 代码示例 User obj GraphServiceClient Users roomC

随机推荐

  • 在泽西岛从 1.9 升级到 Jackson 2.0 不起作用

    我正在使用 Jackson 位于泽西岛 来序列化实体 并且我正在从 Jackson 1 9 迁移到 2 0 我跟着本指南 一开始似乎一切都很顺利 但仔细观察发现 Jackson 1 9 仍在用于序列化我的响应 因此忽略了我的 迁移的 Jac
  • 如何计算沿直线的镜像点?

    在二维平面中 我有一个点和一条线 如何获得沿着这条线的镜像点 当在计算机程序中完成类似的事情时 您可能需要处理的问题之一是仅使用整数算术 或尽可能多 来执行这些计算 假设输入是整数 尽可能以整数进行此操作是一个单独的问题 我不会在这里讨论
  • 如何获取子进程的完整返回值?

    我需要捕获子进程的返回值 问题是 使用等待进程 函数我只能捕获返回值的8位 WEXITSTATUS wstatus 返回子进程的退出状态 这包括 孩子状态参数的最低有效 8 位 在对 exit 3 或 exit 2 的调用中指定或作为参数指
  • 如何使用“sum(iterable,[])”展平嵌套列表? [复制]

    这个问题在这里已经有答案了 我正在使用Python 3 6 我遇到了以下方法来展平嵌套列表sum a 1 2 3 4 5 6 sum a 返回 1 2 3 4 5 6 这里究竟发生了什么 Sum 接受一个可迭代对象 在本例中是一个列表 和一
  • Python 中两个范围列表的交集

    我的一个朋友向我传递了他最近收到的一个面试问题 我对我的解决方案不太满意 问题如下 你有两个清单 每个列表将包含长度为 2 的列表 表示一个范围 即 3 5 表示从 3 到 5 含 的范围 您需要返回集合之间所有范围的交集 如果我给你 1
  • 在 Android 上从 gcm 迁移到 fcm

    我想在 Android 应用程序中从 gcm 迁移到 fcm 我是否需要从 gcm 向 Android 应用程序的老用户发送推送通知 或者我可以通过服务器的新 fcm 发送通知 FCM 工作正常我可以通过 fcm 在我的设备上接收推送通知
  • 不构建核心库时不明智或错误地使用核心类(java.* 或 javax.*)

    当我清理项目时 出现以下错误 2011 10 05 13 47 53 The Basics Dx trouble processing java nio CharBuffer class Ill advised or mistaken us
  • Python:重载特定类型的运算符

    我希望能够让我的类的运算符以我定义的方式与常规类型进行交互 比方说 我有 class Mynum object def init self x self x x def add self other return self x other
  • 如果出现平局,Python 会选择哪个最大值?

    当使用max Python 中的函数查找列表 或元组 字典等 中的最大值 并且最大值存在并列 Python 选择哪一个 是随机的吗 例如 如果一个人有一个元组列表并且一个人选择一个最大值 使用key 基于元组的第一个元素 但有不同的第二个元
  • React 组件中的 Children 属性

    我现在正在学习反应 这是代码的链接 http redux js org docs basics ExampleTodoList html 我有点难以理解这部分代码中发生的事情 const Link active children onCli
  • 强制 JSON.stringify() 发出 NaN / Infinity 或这样做的 JS JSON 库

    我正在研究向使用 JSONRPC 进行客户端 服务器交互的现有科学应用程序添加 NaN Infinity 支持的可行性 许多 JSON 库确实处理 在某些情况下可选 NaN 和 Infs 例如 Python json读取和写入 Java J
  • Java 使用实例方法而不是类/静态方法为每个实例化对象创建唯一 ID

    对此相当陌生 所以我希望标题中的术语正确 我想弄清楚如何创建一个实例方法这将执行以下操作 返回一个ID号 由于每个对象都是从类构造函数创建的 实例化 因此会为其分配一个唯一的整数 ID 号 第一个 ID 号是 1 当实例化新对象时 将分配连
  • MediaPlayer setDataSource 需要最佳实践建议

    看完之后 媒体播放 and 媒体播放器 android 文档我仍然很困惑 需要有经验的建议设置数据源重载方法 我在用MediaPlayer in a Service我的项目中的组件将是前台服务播放音乐时 我的音乐文件 mp3 位于res r
  • Eureka 服务给出请求执行错误?

    请求执行错误 端点 DefaultEndpoint serviceUrl http localhost 8761 eureka 当我在 docker windows 中运行时 它会给出 但是当我在 STS 中的 spring boot 应用
  • 如何识别脚本中是否使用了bash或dash?

    我正在编写一个 bash 脚本 在 Ubuntu 中使用 sh 命令时它会抛出错误 它似乎与 dash 不兼容 我正在学习这个主题 所以我想检测是否使用 dash 而不是 bash 来抛出错误 如何在脚本上下文中检测它 有可能吗 You c
  • 从 Eclipse 导入到 Android Studio 后无法运行任务 ':app:dexDebug" 执行失败

    有一个在 Eclipse 4 4 2 ADT 中运行的 Android 项目 在 Linux Ubuntu 14 10 上运行 我已经导入到 Android Studio 1 1 0 并设法摆脱了最初的编译错误 我想要做的下一件事是在我的手
  • Pandoc:带有 YAML 元数据的模板

    我使用 pandoc 生成带有 YAML 元数据的 index html 我知道从 pandoc 模板迭代关联数组 YAML Author Mastropiero Author Gunter Fraggen TEMPLATE for aut
  • 使用组件进行 Angular 2 表单级别验证

    在 Angular 2 中 如何在自定义组件中添加输入控件 并将其绑定到父组件中的表单控件容器 为简洁起见 简化了以下代码 例如 我有一个表单组件 请注意按钮禁用绑定 Component selector my form template
  • 如何在python中将数据模拟为request.Response类型

    我想写一些测试用例来练习对象检查在 isinstance obj requests Response 逻辑中 在我创建模拟数据作为 requests post 的返回值之后 模拟数据的类型始终是模拟类 这样 我如何重写模拟数据 使模拟数据可
  • 德米特混乱法则

    我希望有人能帮我解释一下德墨忒耳定律 如果我有一个类 我假设它是一个聚合根 并且其中有一个子类的集合 通过聚合根访问这些子类来更新它们的属性是否非法 e g public class Company company has a number