2019 年 6 月
第 34 卷,第 6 期
此文章由机器翻译。
[孜孜不倦的程序员]
裸编码:裸操作
通过Ted Neward |2019 年 6 月
欢迎回来,使用 NOF 的开发人员们。上次,我检查 NakedObjects 如何处理集合,提供能够将多个对象与另一个相关联 (msdn.com/magazine/mt833439)。因为我经历该部分,但是,我介绍了"操作"的代码的概念而无需真正进行任何详细说明。因为操作是为属性的"data"配对"代码",所以应该以查看更多详细信息中的操作 — 特别是,发现操作可以所在的位置,而且在 UI 中的显示方式。
准备好处理裸吗?
操作
NOF 手册描述的操作为"应由用户调用的方法。" 务必要但请注意,这些方法不只是用户的可调用;手动将进入,相同的句子,指出,"它可能还中进行调用以编程方式从另一种方法或另一个对象。" 操作,然后,是在其中定义对象上的行为,和 NOF 将生成用户单击/调用它可发现每个操作的菜单项。
轻松地会想到的一个此类操作就是执行基本的 CRUD 行为上的给定距离的 (或演讲者,就此而言),但是回忆起来 NOF 已处理那些作为一个整体 UI 的核心行为的一部分。关闭主菜单的菜单项,可创建新发言人,其中,请记住,此系列教程的第二个文章中所示 SpeakerRepository,定义 (msdn.com/magazine/mt833268)。编辑发言人后发生的情况选择演讲者和用户选择显示的"编辑"菜单项。事实上,缺少从列表中的唯一操作是删除演讲者,这就是简单的开始位置的能力 — 我现在将添加一个使我可以删除当前可见的说话人的操作。
(我知道,我知道 — 谁想要删除演讲者?我们所有因此 lovable,很难想象,任何人都想要从系统移除演讲者。但与我这一,出于教学目的,如果其他任何内容。假设它们正在停用。或内容。)
若要添加新的操作,我只需将新方法添加到演讲者类型。默认情况下,将域对象上的任何公共方法公开为"操作"菜单中的操作的 UI,这是添加这是非常简单:
public void Delete()
{
Container.DisposeInstance(this);
}
请注意,容器属性是依赖关系注入到每个演讲者上创建或从 SpeakerRepository 返回之后 IDomainObjectContainer 的实例。若要删除持久化的对象 (如添加了 SpeakerRepository CreateNewSpeaker 操作演讲者),容器具有"释放"的该实例。
但是,当我将这添加到演讲者类和运行它,发生某种错误情况 — 具体而言,在删除说话人,收到了缺失的对象有关的错误。NOF 客户端会抱怨,只显示的域对象 — 只需删除演讲者 — 不再存在。这样大量的真正意义上而言,想象一下,和答案是为提供用户界面其他内容,显示,例如的系统,我可以很轻松地从容器中获取再次中所有剩余的发言人列表时如下所示:
public IQueryable<Speaker> Delete()
{
Container.DisposeInstance(this);
return Container.Instances<Speaker>();
}
现在,当用户选择要删除演讲者,UI 会将它们删除时,显示的演讲者和上的生命移动列表的其余部分。(再见,该协议中发表演讲。我们记住你人不堪回首。)
地方,但是,一个问题是,某些域对象具有明确的依赖关系上其他人在系统中,并且任意销毁这些对象而不必考虑这些关联将 sow 混沌测试。(事实上,NOF 将阻止删除之前,首先删除这些关联的对象没有任何关联的对象的对象。) 实际上,这意味着如果说话人具有创建任何访谈,删除演讲者将保留这些孤立的访谈。理想情况下,不允许有创建要删除的一个或多个访谈的发言人。可以将检查内部 Delete 方法,并提供一条错误消息,如果用户选择它并不能跟通过,但通常是不允许用户在一个更好的办法甚至选择不允许他们执行的内容的选项,在 NOF 中你想要完全禁用该操作。
再次重申,NOF 使用命名约定来提供此类功能。通过提供一个方法,以名称"禁用"开始,并继续在你想要禁用 (在本例中"删除") 的操作的名称,可以执行该检查,不久后用户曾经选择操作:
public string DisableDelete()
{
if (Talks.Count > 0)
{
return "Speakers cannot be deleted until their Talks are removed.";
}
return null;
}
请注意,DisableDelete 返回一个字符串,将为空,如果操作是精确地执行,或将向用户显示。(默认情况下,该操作的菜单项将被禁用,因此它不会出现,用户可选择但请记住,可以以其他方式调用操作。)
如果你想要完全隐藏用户的操作?这是一个不同的问题,但 NOF 使用相同的方法 — HideDelete 方法,以指示是否应显示该操作。隐藏和禁用所选显然是一个细微的活动,并可能有些则是更限定,以具有比我; UX 辩论简单地说,选择作为 UX 设计人员或你心中所想将您带。
操作参数
请记住,在许多情况下,操作将需要额外的数据之前可以执行它。操作可能会想要查找具有包含特定搜索词,例如"区块链"或"IoT"的访谈的全部发言人 (希望将其完全从系统删除),这意味着用户必须有机会中,键入搜索词。同样,NOF 致力于 UI 应生成代码本身,这意味着在这种情况下,UI 将检查方法参数和展示为用户提供的机会将必需的输入的用户界面元素的结构原则 就位。您已了解在工作这种机制,在于 SpeakerRepository FindSpeakerByLastName 方法执行相同操作: 接受 NOF 解释来表示它需要要为其搜索,在此之后显示文本框的最后一个名称的字符串参数调用操作。
Naked 发布内容
想起我提到过裸对象世界组成域对象和服务,服务的集合的行为不一定包含域对象上的前一篇文章。NOF UI 实质上,如果服务上的方法将域对象作为其参数之一,并且该参数对其具有"ContributedAction"属性,它需要的表示域对象的菜单上应显示此操作。
想象一下你想用于通知扬声器其讨论已接受大会将 Speaker 对象之外的代码。(这是有意义,实际上,从域建模角度来看,因为通知演讲者具有真正不执行任何操作与正在说话人。) 创建一个服务,然后,如下所示 (注意,要确保它已注册 NOF NakedObjectsRunSettings 类的服务属性中):
public class NotificationService
{
public IDomainObjectContainer Container { set; protected get; }
public void AcceptTalk([ContributedAction] Talk talk)
{
Container.InformUser("Great! The Speaker will be emailed right now");
}
}
当然,该通知的实现需要不止其中一条消息显示给用户,但这并不重要的部分 — 此处的关键在于讨论参数,这将导致此操作才会出现在讨论列表中的 ContributedAction 属性操作。这提供了大量有关代码在系统中,相比在 UI 中显示的显示位置的灵活性。
请注意,就可以参与到组的域对象,以及操作使用相同类型的约定,仅将其应用到的域对象而不是一个集合的参数。例如,如果我想要将通知发送到集合的说话人,我可以从执行操作给定方法,如下:
public void NotifySpeakers([ContributedAction] IQueryable<Speaker> speakers)
{
foreach (Speaker s in speakers)
{
// Send SMS or email or whatever
}
}
从 UI 角度看,说话人的任何集合现在将显示在 (允许用户选择的演讲者将显示在集合中),每个复选框和显示表中的"操作"菜单将具有"通知扬声器"操作显示。作为与所有操作,如果用户输入其他需要 (例如要发送的消息每位演讲者),这将显示为 UI 的一部分之前执行的方法。
总结
操作表示裸对象 Framework 体验中,一个重要的方面,它们的任何应用程序的"业务规则"绝大多数将位于其中。服务可以提供商机和主机的业务逻辑,以确保,但位于域驱动的开发人员会发现最佳机会提供代码来"执行工作。"的域对象上的操作
祝编码愉快!
Ted Neward 是本部位于西雅图的 Polytechnology 公司的顾问、讲师和导师。他写过大量文章,独自撰写并与人合著过十几本书,并在世界各地发表演讲。可通过 ted@tedneward.com 与他联系,也可阅读他的博客 blogs.tedneward.com。
衷心感谢以下技术专家对本文的审阅:Richard Pawson