My comments
(2009-2-3)
在读这章时,对于这章开始的2页概述一定要反复的读。尤其是当读到后续小节,感觉迷失方向的时候,一定要回来再读这部分,这部分是这章的一个高度的概括。
如果不具备会计的知识背景,花半天的时间恶补一下。建议看看《会计学原理(新编)》(徐文彬)。了解几个关键的术语:账户,会计科目,复式记账。
我先云山雾罩的读了一遍,再回头看这章的开始部分,对于Martin的阐述思路了解的清晰了,另外在恶补过基本的会计知识后,对Transaction和Summary Account理解起来老轻松了,真是磨刀不误砍柴功J
Brief Summary
Account:账户
Entry:记账分录
Account can only be added or removed by entries. The entries provide a history of all changes of the account.
Account and Entry
Transactions
Transactions add a further degree of auditability by linking entries together. In a transaction, the items withdrawn from one account must be deposited in another. (我理解这句话的意思其实就是会计中所述的复式记账Double entry,复式记账一般就是指借贷记账)
一般的Transsction就是财务上所说的“一借一贷”,而Multiegged Transsction就是财务上所说的“一借多贷”或者“一贷多借”。
导入以下的会计知识:
这是资产类帐户的余额。如果是负债或所有者权益类帐户,七期初余额、期末余额一般应在贷方。
费用类帐户和资产类帐户一样;收入和利润帐户和负债或所有者权益类帐户。
“借”表示资产增加或负债以及所有者权益的减少;“贷”表示资产减少或负债以及所有者权益的增加.
“有借必有贷,借贷必相等”
Summary account:汇总账户
帐户是根据会计科目开设的。会计科目既有总分类科目和明细科目,帐户也就有总分类帐户和明细帐户。
‘原材料’是一个总分类帐户,它只能概括但应所有原材料的增减变化以其结果。在‘原材料’帐户下面,还要按照每一种原材料分别设置明细分类帐户。
‘应收账款’是一个总括反映应收账款结算情况的总分类帐户,为了详细反映应收账款的结算情况,还必须按每一个客户设置应收账款明细分类帐户。
Memo account:备注账户
备注账户并不需要保持平衡。
No real money leaks from or to a memo account.
Posting rules(簿记规则)
对于Posting rules,Martin要从以下的几个方面来阐述:
1. Posting rules是什么
Posting rules allow us to build active networks of accounts that update each other and reflect business rules.
2. 如何实现簿记规则:Individual instance method
为什么要引入Individual instance method?这是因为簿记规则往往很复杂,不会仅仅是乘以一个系数这么简单。例如计税,不同的金额对应不同的税率。也就是说对于不同的实例(instance)会对应不同的behavior。
3. Posting rules如何被执行
Posting rule execution pattern describes ways in which posting rules can be triggered.
4. Posting rules在哪里定义
Posting rules for many accounts
Choosing entries
Accounting practice pattern: 这是为了给Posting rules进行分类
The source of an entry
Balance sheets and income statements(资产负债表和损益表)
Corresponding account
Specialized account model
Transactions
Account, entry和Transactions这三者之间的关系通过UML体现。这是这章的基础。
entry和Transactions之间的关系就如同是先有鸡还是先有蛋的问题。因为有约束条件,如果没有创建Transactions就不能创建entry;同样没有entry也不能创建Transactions,这也是因为有约束条件。
解决方法就是Transactions负责创建entry,entry的创建操作仅能由Transactions来访问。但是这样或许会违背约束,No problem,我们可以定义规则就是:所有的public operations必须以所有约束条件都得到满足为结束条件。
Transactions这个概念在实际的业务系统中是不存在的,它其实是人造的(artifical),是为了便于数据管理,毕竟我们现在用的还是关系型数据库以及面向对象的设计方法哈。
Summary Account
注意这里Summary Account的记账方式是和业务系统不同的。在实际的财务管理中,我们会在汇总账户和明细账户中分别编制会计分录(Entry),而在业务系统中并不是这样的,按照Martin的叙述:
1. The entries of a summary account are derived from the component’s entries in a recursive manner.
2. post entries only to detail accounts not to summary accounts.
Posting Rule
1. 什么是Posting Rules?(簿记规则)
Posting rule looks at a particular account and, when it sees an entry, creates another entry.
简单的Posting Rule就是乘以一个因子,如图Figure6.8.但是复杂的,例如计税就要采用Figure6.9的模式。
注意这也就是为什么要引入Individual instance method的原因。(这个我也是看了2遍才明白的啊)
这句话很重要:We want the behavior to vary with each individual instance.
所以不能通过类继承实现。Individual instance method就是讨论如何实现“the behavior to vary with each individual instance”。
1. Individual instance method-如何实现簿记规则:
1) Singleton Class单一实例
2) Strategy Pattern
3) 使用内部的case语句
在Posting Rule上我们要定义一系列的操作。
在Posting Rule上定义computeFor。ComputeFor包含case语句去调用上面的一系列的操作。
4) 使用带参数的方法(Parameterized Method)
5) 解释器Interpreter
最后Martin给出了选择实现方法的原则。他的首选是:Parameterized Method。
不过我认为如果是做产品,解释器Interpreter是不二的选择。因为实际的业务系统的复杂程度绝不是任何人在产品开发过程中可以想象到的,最大的灵活性是追求的唯一目标。用开发的复杂性换取实施的灵活性。
2. Posting Rules在哪里执行
原则:Separate the strategy of firing the posting rules from the rules themselves as much as possible to reduce the coupling between these mechanisms.
A. Eager Firing
当触发账户中产生一个entry,posting rules就会被触发执行。
有2种方式:
A.在创建Transaction或entry的方法中posting rules被触发。
B.使用Observer模式。Make Posting rules observer of their trigger account.这种方式比较复杂,尽量避免使用。
B. Account-based Firing基于账户的触发
这是一种延时处理。对应每个账户维护一个未处理交易条目列表,尤其适用于cyclic accounting system(循环记账系统)。每天account处理一次。
一定要注意账户的处理顺序。
C. Posting-rule-based Firing
和Account-based Firing相似,只是Posting rule负责管理未处理交易条目列表。这种触发方式比较复杂,尽量避免使用哈。
D. Backward-chained Firing
以当前操作帐户(processing account)为输出->找到posting rule->再推导出对应的account(这就是要找出哪个帐户触发的当前操作帐户)->对这些帐户进行更新
E. 如何选择posting rule的执行方式:
要基于一下2点来考虑:
ü Posting rule执行的时间
ü 希望在何处捕获错误
Martin对这几种方法的评价是:
Eager Firing没有灵活性
Account-based Firing和Posting-rule-based Firing都具有很好的灵活性,帐户结构简单使用前者,若复杂,则使用后者。
4. Posting Rules在哪里定义
两种方法:
1) knowledge and operational level,posting rules定义在account type上。
2) 使用summary account,把posting rules定义在summary account,所有子帐户也都遵循同样的posting rules
对于这两种不同方法的选择的最主要的因素就是:the degree of difference in the behavior of the candidate accounts and account types.
Choosing the entry
有三种方法:
1) Getting all entries back and then doing a selection
2) Providing a selection-specific method
3) Using a filter。Filter就是一个封装了查询query的对象。Pattern见Figure6.24的时序图。