我只是想知道规范模式是否毫无意义,给出以下示例:
假设您想检查客户的帐户中是否有足够的余额,您可以创建如下规范:
new CustomerHasEnoughMoneyInTheirAccount().IsSatisfiedBy(customer)
但是,我想知道的是,我可以通过在 Customer 类中使用 Property getter 来实现与规范模式相同的“好处”(例如只需要更改适当的业务规则):
public class Customer
{
public double Balance;
public bool HasEnoughMoney
{
get { return this.Balance > 0; }
}
}
来自客户端代码:
customer.HasEnoughMoney
所以我的问题确实是;使用属性 getter 来包装业务逻辑和创建 Specification 类有什么区别?
提前谢谢大家!
最佳答案
是的,这是没有意义的。
The Wikipedia article详细批评了这种模式。但我看到最大的批评仅仅是 Inner-Platform Effect .为什么要重新发明 AND 运算符?请务必阅读维基百科文章以获取完整图片。
Henry,您认为 Property Get 更优越是正确的。为什么要避开一个更简单、易于理解的 OO 概念,而选择一个在其概念中不能回答你的问题的模糊“模式”?这是一个想法,但不是一个好主意。这是一种反模式,一种不利于您的模式。
您已经问过有什么区别,但更有用的问题是,什么时候应该使用规范模式?
永远不要使用这种模式,这是我对这种模式的一般规则。
首先,您应该意识到此模式并非基于科学理论,它只是某人想象的任意模式,它使用特定的类建模 {Specification, AndSpecification, ...}。考虑到更广泛的领域驱动理论,您可以放弃这种模式,并且仍然有每个人都熟悉的更好的选择:例如,命名良好的对象/方法/属性来建模领域语言和逻辑。
杰弗里说:
a Specification object is just a predicate wrapped up in an object
领域驱动是这样,但规范模式不是这样。 Jeffrey 全面描述了一种情况,人们可能希望动态构建 IQueryable 表达式,以便它可以在数据存储(SQL 数据库)上高效执行。他的最终结论是,您不能按照规定使用规范模式来做到这一点。 Jeffrey 的 IQueryable 表达式树是隔离逻辑规则并将它们应用于不同组合的另一种方法。正如您从他的示例代码中看到的那样,它非常冗长且使用起来非常笨拙。我也无法想象任何需要这种动态复合 Material 的情况。如果需要,还有许多其他更简单的技术可用:-
我们都知道您应该最后优化性能。试图在这里实现 Bleeding edge使用 IQueryable 表达式树,是一个陷阱。相反,从最好的工具开始,首先是一个简单简洁的 Property Getter。然后测试、评估剩下的工作并确定优先级。
我还没有遇到过这种规范模式是必要的/更好的情况。当我确实遇到假设的情况时,我会在这里列出它们并反驳它们。如果我遇到好的情况,我会用一个新的部分来修改这个答案。
RE: zerkms 回答
Because with the specification class you can create new criterias [sic] without modification of the objects themselves.
C# 已经适应了这种情况:
这些是全局范围内传授的思想,大多数程序员已经自然而然地理解和使用。
在我接手的项目中,我确实遇到过规范模式等反模式。它们通常位于单独的项目/库中(项目的过度碎片化是另一种糟糕的做法)并且每个人都害怕扩展对象。
关于c# - 规范模式毫无意义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4446177/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
如何在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
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度; 在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl
我正在为毕业设计开发GEM,TravisCI构建不断失败。这是我在Travis上的链接:https://travis-ci.org/ricardobond/perpetuus/builds/8709218构建错误是:$bundleexecrakerakeaborted!Don'tknowhowtobuildtask'default'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_wrapper:14:in`eval'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_