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