MARC数据字段相互之间存在密切的联系,例如200$f$g中的内容,可以复制提供给创建701/702著者字段内容用;010$a中的ISBN号,可以为创建出版社210$a$c和出版地代码102$a$b提供线索。
或者,一些字段子字段的内容,需要从数据字典,或者从外部数据库中选用值。
凡此种种需求,dp2编目系统都通过一个数据加工模块来实现。
由于这些需求具有很大的弹性,用户经常要对其进行配置修改,除了具有数据密集的特点,还有操作逻辑复杂的特点,因此开发者决定用二次开发脚本的方式加以实现。
在初期,软件用户可以使用缺省提供的功能,并不感觉到脚本程序的存在;随着用户需求的增长,对系统熟悉程度的提高,就可以对脚本程序进行二次开发,扩展本馆的特色功能。
下图是在MARC编辑器中用Ctrl+A调出的脚本功能菜单:
对话框中有一个“自动执行加亮事项”chechbox,如果处于勾选状态,则每当对话框出现的时候,如果其中有而且只有一项处于加亮状态,就自动结束对话框去执行加亮事项要求的功能。
熟练的编目员很喜欢这个功能。
在数据加工事项定义的时候,可以定义这个事项针对哪些字段、子字段位置敏感。例如,“加入种次号”的功能,自然是对905$e这个子字段位置敏感,当插入符处于这个位置的时候触发Ctrl+A,那么“加入种次号”事项应当是发亮的。
所有的数据加工功能,都是在库下的cfgs/autogenerate.cs文件中定义的。这是一个用.NET C#语言书写的脚本程序。虽然名为脚本程序,似乎暗示了功能的局限性甚至简陋,但是实际情况却不是这样,且听我下面解释。
===
dp2编目系统,或者这个大系统中的所有模块,数字平台公司的开发人员进行的开发活动,可以称为“一次开发” ,也就是写出、编出、造出这个软件的根本所在。而上述提供给用户增值开发的手段和方式,可以称为“二次开发”。二次开发和一次开发的重点自然是不同,二次开发不是要去发明车轮,而是要调度好、使用好已有的大部分功能。
为着这个目的,一次开发需要和二次开发进行配合。虽然在一次开发的时候,也许二次开发在哪里还未可知呢,但是,开发者应当意识到,他所建立和一直在使用的程序架构,数据模型,不但是小小的开发团队在使用,而且将来一定要被二次开发用到。所以,结构是否合理、简易通俗,变量命名是否直截了当、便于记忆理解,都是关系到二次开发成功的核心要素。
从这个意义,dp2编目系统从一次开发的时候就明白,它是一个最终“面向二次开发的系统”。
具体来说,从程序对象结构来说,用户从视觉上观察到并认同的一些窗口对象,例如框架窗口,检索窗,详细窗,在一次开发或者二次开发的视角,就是MainForm,SearchForm,DetailForm这样命名的类、对象。
例如,在数据加工脚本中要使用MARC编辑窗,比方说要像键盘输入一样通过程序代码插入字段、子字段内容,可以通过this.DetailForm.MarcEditor这样的代码来指明MARC编辑器对象,通过:
Field field_200 = this.DetailForm.MarcEditor.Record.Fields.GetOneField("200",0);
这样一行代码,获得200字段对象;通过:
SubfieldCollection subfields_200 = field_200.Subfields;
这样一行代码,获得200字段中的子字段集合;通过:
Subfield subfield_f = subfields_200["f"];
这样一行代码,获得其中的$f子字段。
可以说,二次开发的代码,足以做任何复杂的事情。因为它从技术手段上,和一次开发使用同样的开发语言C#,并不弱了什么。当然,一次开发和二次开发的目的不同,手段也有所不同。二次开发不会写出几千行、上万行的代码,非常复杂地去从头实现一个功能,这本是一次开发的任务。数字平台公司会竭尽全力,在软件生命周期的全过程中,为图书馆业务功能提供足够的一次开发模块,也就是有价值的高质量的预制“组件”;用户可以灵活有效地运用这些组件,享受这些组件带来的功能。
dp2系统以名字空间DigitalPlatform提供了许多组件。二次开发可以享用全部这些组件。
二次开发对一次开发有推动的作用。用户发展出来的二次开发代码,经过归纳测试后可以提升到一次开发代码,含入软件的预制组件中。一个有用软件的生命周期通常都会很长,因此,在软件投入运行后不断升级、成熟的过程中,这个二次开发的推动作用很重要,效果也应是很明显的。相信dp2现有的这些设施,是一个很好的开端。