public class BigPerformance
{
public decimal Value { get; set; }
}
public class Performance
{
public BigPerformance BigPerf { get; set; }
}
public class Category
{
public Performance Perf { get; set; }
}
如果我打电话:
Category cat = new Category();
cat.Perf.BigPerf.Value = 1.0;
我认为这打破了Law of Demeter / Principle of Least Knowledge?
如果是这样,如果我有大量的内部类属性,我该如何解决这个问题呢?
答案 0 :(得分:9)
Martin Fowler最喜欢的一句话:
我希望它被称为 偶尔有用的建议 Demeter的
http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx
答案 1 :(得分:3)
如果您正在谈论Demeter法,例如“不要打电话给邻居的邻居”,您可以将其委托给其他做您想做的事情的方法。
从你的例子中我猜你要重置性能值或其他东西。您可以修改示例代码,以便它们固有地链接在一起:
Category cat = new Category();
cat.resetPerf();
代码将类似于此:
public class BigPerformance
{
//constructors 'n stuff
public static decimal DEFAULT;
public decimal Value {get; private set;}
public void reset() {
Value = BigPerformance.DEFAULT;
}
}
public class Performance
{
//constructors 'n stuff
private BigPerformance BigPerf {get; set};
public reset() {
BigPerf.reset();
}
}
public class Category
{
// constructors 'n stuff
public Performance Perf {get; private set;}
public resetPerformance() {
Perf.reset();
}
}
这样Category
类不需要知道如果重置值,以防默认值不同或将来更改类型。
就个人而言,如果变更风险很低,我会选择juharr's answer。
答案 2 :(得分:1)
Category cat = new Category();
cat.Perf.BigPerf.Value = 1.0;
是
Category cat = new Category();
cat.GetPerf().GetBigPerf().SetValue(1.0);
如果维基百科的定义是正确的,那么它就违反了规则:
.. [M]对象O的方法M可能只有 调用以下方法 各种物体:
- O本身
- M的参数
- 在M
中创建/实例化的任何对象- O的直接组件对象
- 一个全局变量,可由O访问,范围为M
特别是,对象应该避免调用另一个方法返回的成员对象的方法
如果您担心3紧密耦合,则删除公共访问器并在Category上添加方法以设置值。然后将Performance和BigPerformance重构为私有成员。
答案 3 :(得分:1)
如果你始终牢记你的课程的可测试性并使用IoC,你会发现你不必担心LoD。
以这种方式看待它
我将如何测试
Category
?我 不希望它自动创建 使用慢速的Performance
文件系统。我们通过一个IPerformance
到Category
并取代实际的实施 使用虚拟Performance
实例。我如何测试
Performance
? 我不希望它自动化 创建一个BigPerformance
制作一个 连接到数据库。我们通过一个IBigPerformance
到...Performance
并替换实际 用虚拟实现BigPerformance
实例。
...
你显然注意到了模式
您的代码将在
行中BigPerformance BigPerf = new BigPerformance();
BigPerf.Value := 1.0;
Performance Perf = new Performance(BigPerformance);
Category cat = new Category(Performance);
(This would be retrieved from a factory.)
它看起来(并且在短期内可能是)更多的工作,但从长远来看,通过能够孤立地测试你的课程,这些好处将得到回报。
查看Misco Hevery's博客,了解此主题和其他主题。
答案 4 :(得分:0)
这并不违反得墨忒耳法,因为你正在使用公共合同。