前言
之前关于实体和值对象的文章中有提过迪米特发则以及告诉而非询问原则。偏向于值对象的设计方法,今天参考马丁福勒的文章https://martinfowler.com/bliki/TellDontAsk.html 了解下广义的告诉而非询问原则。真是遗憾没有早点知道这些大拿!
原则概述
Rather than asking an object for data and acting on that data, we should instead tell an object what to do. This encourages to move behavior into an object to go with the data.
我们应该直接通过对象获取业务逻辑的结果,而不是根据对象的状态自己做业务逻辑。这要求我们把业务逻辑封装到拥有相关数据的对象中。这其实也是我们之前提到的信息专家提出的要求。
举例来说
询问
- 有一个监控对象如下,业务逻辑是如果value超过limit,那么执行报警
class AskMonitor...
private int value;
private int limit;
private boolean isTooHigh;
private String name;
private Alarm alarm;
public AskMonitor (String name, int limit, Alarm alarm) {
this.name = name;
this.limit = limit;
this.alarm = alarm;
}
public int getValue() {return value;}
public void setValue(int arg) {value = arg;}
public int getLimit() {return limit;}
public String getName() {return name;}
public Alarm getAlarm() {return alarm;}
- 业务逻辑如下,首先获取到AskMonitor对象,然后取出里边的value和limit做对比,如果超限就报警
public void business(){
AskMonitor am = new AskMonitor("Time Vortex Hocus", 2, alarm);
am.setValue(3);
if (am.getValue() > am.getLimit())
am.getAlarm().warn(am.getName() + " too high");
}
告诉
- 下面是告诉的业务逻辑,自己封装了数据和业务逻辑
class TellMonitor...
private int value;
private int limit;
private boolean isTooHigh;
private String name;
private String name;
private Alarm alarm;
public void setValue(int arg) {
value = arg;
if (value > limit) alarm.warn(name + " too high");
}
- 业务逻辑调用如下
public void business(){
TellMonitor tm = new TellMonitor("Time Vortex Hocus", 2, alarm);
tm.setValue(3);
}
总结
可见告诉而非询问和DDD非常契合,鼓励我们多写充血模型而不是贫血模型