2.74
练习 2.74 Insatiable Enterprise 公司是一个高度分散经营的联合公司,由大量分布在世界各地的分支机构组成。公司的计算机设施已经通过一种非常巧妙的网络连接模式连接成一体,它使得从任何一个用户的角度看,整个网络就像是一台计算机。在第一次试图利用网络能力从各分支机构的文件中提取管理信息时,Insatiable 的总经理非常沮丧地发现,虽然所有分支机构的文件都被实现为 Scheme 的数据结构,但是各分支机构所用的数据结构却各不相同。她马上召集了各分支机构的经理会议,希望寻找一种策略集成起这些文件,以便在维持各个分支机构中现存独立工作方式的同时,又能满足公司总部管理的需要。
请说明这种策略可以如何通过数据导向的程序设计技术实现。作为例子,假定每个分支机构的人事记录都存放在一个独立文件里,其中包含了一集以雇员名字作为键值的记录。而有关集合的结构却由于分支机构的不同而不同。进一步说,某个雇员的记录本身又是一个集合(各分支机构所用的结构也不同),其中所包含的信息也在一些作为键值的标识符之下,例如 address 和 salary。特别是考虑如下问题:
a) 请为公司总部实现一个 get-record 过程,使它能从一个特定的人事文件里提取聘个特定的雇员记录。这一过程应该能应用于任何分支机构的文件。请说明各个独立分支机构的文件应具有怎样的结构。特别是考虑,它们必须提供哪些类型信息?
b) 请为公司总部实现一个 get-salary 过程,它能从任何分支机构的人事文件中取得某个给定雇员的薪金信息。为了使这一操作能够工作,这些记录应具有怎样的结构?
c) 请为公司总部实现一个过程 find-employee-record,该过程需要针对一个特定雇员名,在所有分支机构的文件去查找对应的记录,并返回找到的记录。假定这一过程的参数是一个雇员名和所有分支文件的表。
d) 当 Insatiable 购并新公司后,要将新的人事文件结合到系统中,必须做哪些修改?
需要为公司建立一个操作表,大致如下:
操作 \ 分公司 | 分公司1 | 分公司2 | ... |
---|---|---|---|
get-record | get-record-1 | get-record-2 | ... |
get-salary | get-salary-1 | get-salary-2 | ... |
find-employee-record | find-employee-record-1 | find-employee-record-2 | .. |
d) 当 Insatiable 购并新公司后,需要实现一套该公司特定的操作的具体实现,并在总公司的操作注册表中注册该公司即可。
a) 每个分支公司的记录,需要包含其所在的分支机构的编号信息。如
(list branch-number employee-records)
从而, get-record
可以这样实现:
(define (get-record records)
(define branch-number (car records))
(cond
((= branch-number 1) (get-record-1 records))
((= branch-number 2) (get-record-2 records))
(else (error "Unknown branch -- BRANCH-NUMBER" branch-number))
)
)
b) 同样,每个分支的薪金记录也需要带上分支机构编号信息:
(list branch-number salary-info)
(define (get-salary salary-info)
(define branch-number (car salary-info))
(cond
((= branch-number 1) (get-salary-1 salary-info))
((= branch-number 2) (get-salary-2 salary-info))
(else (error "Unknown branch -- BRANCH-NUMBER" branch-number))
)
)
c) branch-records 结构如下:
(list branch-number records)
all-records 结构如下:
(list all-records (list branch-records-1 branch-records-2 ...))
(define (find-employee-record-from employ branch-records)
(define branch-number (car branch-records))
(cond
((=branch-number 1) (find-employee-record-1 employee branch-records))
((=branch-number 2) (find-employee-record-2 employee branch-records))
(else '())
)
)
(define (find-employee-record employ all-records)
(cons
(find-employee-record-from employ (car all-records))
(find-employee-record employ (cdr all-records))
)
)