假设您有一个班级Car
,其中有一个Driver
。如果你想访问驱动程序的年龄,你可以这样做:
@car.driver_age
而不是
@car.driver.age
如果您已在Car
模型中委派了驱动程序的年龄属性(前缀设置为true)。
但是,如果你还有一个Passenger
课程并且你想要访问汽车中的乘客数量,以下是不是违反了得墨忒耳法则,或者我的想法过于热心:
@car.passengers.count
答案 0 :(得分:5)
我认为count
非常普遍,以至于我觉得没有必要代理这个电话。我会问自己这个问题:
将来可能会有
passengers
的实施,但不会回复count
吗?
由于passengers
极有可能永远是容器类型,并且Ruby中的所有容器类型(Array
,Hash
,...)都会以count
的方式响应你会期望,我会用“不”回答这个问题,因此坚持使用@car.passengers.count
。
修改
但如果你是严格的,那你确实违反了得墨忒耳法则。例如,考虑一个根本没有乘客的班级RobotCar < Car
。现在,在LoD之后,你可以简单地从方法0
返回car.passenger_count
,而当不跟随LoD时,你必须从passengers
返回一个空容器,以免破坏其他代码。 / p>
最后,你必须自己决定接口改变的可能性。如果你非常肯定它不会改变,那么我想可以不服从LoD。
答案 1 :(得分:1)
如果你的班级/方法需要知道司机的年龄,它应该直接引用司机:
@driver.age
或者乘客:
@passengers.count
通过@car
访问这些做出了许多假设。想象一下没有驾驶员或没有乘客的玩具车的自动驾驶汽车。 @car.driver_age
或@car.passengers_count
没有多大意义。
答案 2 :(得分:1)
LoD不只是“计算点数”,并且用点数下划线也无济于事。
汽车有一个有年龄的司机;对此没什么不合理的。
(嗯,不是真的,因为我们即将进入无人驾驶汽车的时代,这种模式可能不会解释这个问题,但这是一个单独的问题。)
函数的Demeter定律要求对象O的方法M只能调用以下类型对象的方法:
- O本身
- M的参数
- 在M
中创建/实例化的任何对象- O的直接组件对象
醇>特别是,对象应该避免调用 另一种方法返回的成员对象的方法。