public class Person
{
public IList<String> SpecialBirthPlaces;
public static readonly DateTime ImportantDate;
public String BirthPlace {get;set;}
public DateTime BirthDate
{
set
{
if (BirthPlace!=null &&
value < ImportantDate &&
SpecialBirthPlaces.Contains(BirthPlace))
{
BirthPlace = DataBase.GetBirthPlaceFor(BirthPlace, value);
}
}
}
}
这是在我的域模型中封装一个简单规则的尝试。我试图捕捉的规则是:由于某种原因,当我们更新一个人的出生日期(例如,原始用户输入中有错误)时,我们需要检查该人的出生地并将其替换为来自数据库,如果它在我们的数据库中列为特殊出生地。
但是,我在实现它时遇到了 2 个问题:
此规则修改域实体状态(属性),我需要在用户界面中反射(reflect)此更改。我的领域模型是 POCO。我可以将此逻辑放在 ViewModel 中,但这是错误的,因为它不是 UI 逻辑。这是我需要捕获的重要域规则。
我的 SpecialBirthPlaces 列表非常大,我不想每次从数据库中获得客户时都填充它。此外,当规则满足时,我需要更换出生地。正如我所说,特殊出生地和替代品的列表非常大,存储在数据库中。
如何以 DDD 风格实现我需要的逻辑?
最佳答案
我封装这个问题的方法,即修改跟踪,是使用工作单元模式。我的 DDD 存储库与一个工作单元相关联,我可以查询工作单元以查找从任何存储库获得的任何实体集,以查看哪些已修改。
至于大集合,它似乎是一个只读集合。处理这个问题的一种方法是在它被访问时在本地预加载和缓存,然后存储库可以对内存版本运行查询。我使用 NHibernate,用它很容易处理这种情况。如果它方式太大而无法存储在 RAM 中(例如 100 MB 或更多),您可能需要针对它进行特殊情况存储库查询,以便 SpecialBirthPlaces.Contains(BirthPlace ) 查询在数据库上执行(可能在存储过程中,哈!)。您可能希望将 SpecialBirthPlaces 表示为实体存储库,而不仅仅是一大串字符串,这将使“查询”模式使您无需加载整个内容。
在这个冗长的叙述之后,这里有一些例子:
public class BirthPlace
{
public String Name { get; set; }
}
public class SpecialBirthPlace : BirthPlace
{
}
public class Person
{
public static readonly DateTime ImportantDate;
public BirthPlace BirthPlace { get; set; }
public DateTime BirthDate
{
get; private set;
}
public void CorrectBirthDate(IRepository<SpecialBirthPlace> specialBirthPlaces, DateTime date)
{
if (BirthPlace != null && date < ImportantDate && specialBirthPlaces.Contains(BirthPlace))
{
BirthPlace = specialBirthPlaces.GetForDate(date);
}
}
}
使用一种方法来传递更正的出生日期是一个更好的设计,因为它通过参数告诉您实际更正出生日期需要什么:SpecialBirthPlace 实体的存储库(即集合)和正确的日期。这种显式契约清楚地表明域在做什么,并且仅通过阅读实体契约就可以清楚地了解业务需求,其中将整个集合置于实体状态中隐藏它。
现在我们已经将 BirthPlace 变成了一个实体,我们可以看到可能还有一个优化可以使领域模型更扁平一些。我们真的不需要特化 BirthPlace 但我们确实需要指出它是否特殊。我们可以向对象添加一个属性(有些人不喜欢域对象的属性,但我不这样做,因为它使查询更容易,尤其是使用 LINQ)来指示它是否特殊。然后我们可以完全摆脱 Contains 查询:
public class BirthPlace
{
public BirthPlace(String name, Boolean isSpecial = false)
{
Name = name;
IsSpecial = isSpecial
}
public String Name { get; private set; }
public Boolean IsSpecial { get; private set; }
}
public class Person
{
public static readonly DateTime ImportantDate;
public BirthPlace BirthPlace { get; set; }
public DateTime BirthDate
{
get; private set;
}
public void CorrectBirthDate(IRepository<BirthPlace> birthPlaces, DateTime date)
{
if (BirthPlace != null && date < ImportantDate && BirthPlace.IsSpecial)
{
BirthPlace = birthPlaces.GetForDate(date);
}
}
}
关于c# - DDD(Domain Driven Design),如何处理实体状态变化,封装需要处理大量数据的业务规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8269784/
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d