public House
{
WeatherStation station;
public float getTemp() {
//Law of Demeter has been violated here
return station.getThermometer().getTemperature();
}
}
public House
{
WeatherStation station;
public float getTemp() {
//Law of Demeter has been preserved?
Thermometer thermometer = station.getThermometer();
return getTempHelper(thermometer);
}
public float getTempHelper(Thermometer thermometer)
{
return thermometer.getTemperature();
}
}
在上面的代码中,您可以看到两个不同的 House 类定义。两者都有 getTemp() 函数,第一个违反了德米特定律,但第二个保留了它(根据 Head First Design Patterns 书)。
问题是我不太明白为什么第二类保留德米特定律, getTemp() 函数仍然有 station.getThermometer() 调用,这(应该?)违反了德米特定律。
“仅使用一个点” - 我在维基百科上找到了这一点,这可能适用,但我仍然需要更详细的解释 - “特别是,一个对象应该避免调用由另一个方法返回的成员对象的方法”(维基)。
那么有人可以解释为什么第二个代码示例不违反法律吗?第二种方法与第一种方法的真正区别是什么?
我想关于这个主题可以进行很多讨论,但根据我的解释,德墨忒尔定律的目的是……
“你不想从车站得到温度计。你想从车站得到温度。”
从现实生活中的情况来考虑。你打电话给气象站,你不会问他们:“你大楼外面的温度计显示了什么?”你问他们:“现在的温度是多少?”他们在建筑物外部安装了温度计,这一事实与您无关。也许他们用指向窗户的红外激光代替了温度计。这对你来说并不重要。他们如何获得信息不是你关心的,你只需要这些信息。
所以,为此,你最终会得到这样的结果:
public House
{
private WeatherStation _station;
public House(WeatherStation station)
{
_station = station;
}
public float GetTemperature()
{
return _station.GetTemperature();
}
}
public WeatherStation
{
private Thermometer _thermometer;
public WeatherStation(Thermometer thermometer)
{
_thermometer = thermometer;
}
public float GetTemperature()
{
return _thermometer.GetTemperature();
// This can be replaced with another implementation, or any other
// device which implements IThermometer, or a hard-coded test value, etc.
}
}
这会导致多层嵌套,这看起来确实有点令人讨厌。但请记住,每个级别虽然目前被称为完全相同的东西,但含义略有不同。它不是really代码重复(如果重复的代码具有不同的含义)。你稍后可以用这样的东西打破链条:
public House
{
private WeatherStation _station;
public House(WeatherStation station)
{
_station = station;
}
public WeatherInfoDTO GetCurrentWeather()
{
var info = new WeatherInfoDTO();
info.Temperature = _station.GetTemperature();
//...
return info;
}
}
public WeatherInfoDTO
{
//...
}
public WeatherStation
{
private Thermometer _thermometer;
public WeatherStation(Thermometer thermometer)
{
_thermometer = thermometer;
}
public float GetTemperature()
{
return _thermometer.GetTemperature();
// This can be replaced with another implementation, or any other
// device which implements IThermometer, or a hard-coded test value, etc.
}
//...
}
通过不对顶层进行硬编码来实现Thermometer
您可以轻松重构以支持此类内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)