1)“请假”这个业务基本不会变化的东西:
“要请假的人”向“负责审批的人”发出请求,“负责审批的人”进行响应。请求的内容(请假条):某人某时因某事请假若干天时间。响应的内容:同意或不同意。
2)“请假”这个业务会发生变化的东西:
至于怎么发出请求,这个容易产生变化,比如除了本人亲自填写,别人也可以代写,甚至可以先口头说一下,事后补登记。
还有怎么进行响应,也容易产生变化,可能根据请假的天数要求不同级别的人来审批,也可能根据请假者的不同职位要求不同级别的人来审批。
但不管怎么样,“请求”与“响应”的内容是基本不变的,发出“请求”和进行“响应”的人,可能会产生变化,此时可以设计出两个角色“请求者”和“响应者”来支持这种变化。我们用这些相对不变的东西来对抗变化。比如上面,出现根据不同请假的天数,由不同的人来审批的需求时,可以采用“责任链”模式进行重构或设计。
在图书馆借书、还书的业务场景,我认为不宜抽象为书的入库、出库。毕竟这与图书馆购买新书的业务场景,有显著的区别。借书、还书的业务场景重点要去描述的不是图书馆少了还是多了几本书,而是谁何时借了哪几本书,谁何时还了哪几本书,根据图书馆的规章制度(业务规则),要怎样进行处理。
找出需求中相对稳定的东西,比较难。有一个可以尝试使用的技巧,就是在考虑业务时先将用户“排出”在外。比如IceQi的例子—用户描述:我要向给领导请假。我会先考虑什么是请假,考虑请假中什么是不容易变化的东西,比如请假条、批准条;接着考虑到参与请假这个活动的人非常多变,此时就有必要进行抽象出“请求者”和“响应者”两种角色,来包容各种各样的“用户”。
抽象的本意就是从多个具象中提取出不变的东西,可以称之为共性。最开始,我们无法确定什么是不变时,不必急于抽象和设计,这往往会弄巧成拙,不妨在需要重构时再进行抽象,因为此时我们可能会比较容易觉察出哪些东西不变了,也就是有了对抗变化的必要基础了。
觉得showerxp和IceQi说的用户故事蛮有趣的,乐于参与其中。但抽象也不要把业务核心特征都给抽调了,比如showerxp将借书、还书的等基本特征都从业务模型中抽离,我个人是觉得不妥。
抽象的力量,不容否认。但不恰当或过分的抽象,很容易把自己搞糊涂,有限的智力再也无法应付。就像真理再进一步,可能成为谬论;抽象偏差了或过分了,我们可能就开始变傻了。
Edsger W. Dijkstra说得非常好:"The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise." Edsger W. Dijkstra, "The Humble Programmer", October 1972