不论是理论上还是实用上,代码重用都是编程的一个重要议题。可以从两个角度来讨论代码重用。

一是逻辑上代码以怎样的方式被重用。既可以通过面向对象的思想普及以来耳熟能详的继承的方式。比如先建了一个车的基类,再从它衍生出轿车、卡车、大客车等子类,基类车的功能就被这些子类重用了。另一种途径是从函数被发明起就一直被使用的组合。例如我们已经有了轱辘、轴、车斗、木杆等部件,就可以组合出一辆三轮车。

第二个角度是实体上代码以怎样的方式被重用。从需要连接的静态库文件、可以动态加载的库到直接引用的脚本文件,都有各自的特点。

Lotus Notes中的代码重用也可以从这两个角度来分析。各种二进制的设计元素,如表单、视图,都是采用组合的方式重用代码,表单中可重用的部份被做成子表单,建立多个视图时想要节省工作量,唯一做法就是将列作为组件重用。至于LotusScript和Java代码,则像其他编程语言一样,继承和组合两种方式都可选用。

LotusScript作为Xpages被引入之前Notes最主要的编程语言,是一种解释型的脚本语言,但又和VB一样,原始代码会被先编译成一种中间形式的代码,使用LotusScript的其它Lotus软件,如Lotus 1-2-3、Lotus Word Pro等,有些可以把编译过的LotusScript以扩展名为.LSO的文件形式保存和引用。Lotus Notes不支持这种方式,而是将编译过的代码和原始代码一同保存在包含此LotusScript的设计元素里。在代理、脚本库、表单等含有LotusScript的设计元素里,分别可以看到数据类型为Agent LotusScript的以下字段$AssistAction_Ex、$ScriptLib_O、$$FormScript_O、$$Script_O,其中的内容都是被称为Script Object的编译过的LotusScript。这样在解释运行前的编译,虽然使LotusScript运行得更快,但也给位于不同设计元素的脚本之间的调用带来了一个副作用。可复用的脚本通常集中置于脚本库中,表单、代理等再引用这些脚本库。保存于这些调用方设计元素内的编译过的脚本包含了脚本库里各个可供调用的公用项目如变量、函数、类的信息。

当脚本库中的代码发生变化被重新编译后,调用它的设计元素保存的那些公用项目的信息就可能与脚本库的实际不一致,这就导致了常见的运行时错误Type mismatch on external name <name>和Cannot find external name <name>。如果被使用的变量、函数真的发生了变化,如被删除、修改名称、参数和返回类型等等,脚本当然无法执行,与是否编译无关。但实际上,即使这些都没有发生变化,这些错误也时常会产生。要避免它们,就需在修改了脚本库后,把使用到它的设计元素里的脚本编译一遍,也就是把它们稍作修改再保存,或者是使用Designer的重新编译所有LotusScript命令。一般来说,脚本库的各个公用项目声明发生变化,调用方一定需要重新编译;如果是私有项目如私有变量或一个类的私有成员被修改,或者函数的内部代码发生变化,调用方不需要重新编译。

在重用的实体方面,某个应用要重用其他应用的代码都必须置于同一个数据库中,即每重用一次,都创建了这些代码的一份副本,而不是引用同一份代码。50. 替换设计和刷新设计——Lotus Notes的程序部署和更新之理论51. 替换设计和刷新设计——Lotus Notes的程序部署和更新之实践讨论的Lotus Notes程序继承设计的很多问题,都和这个事实有关。再加上上面介绍的关于编译的问题,就使得通常模版发生变化后,要更新使用它的应用程序,不仅要替换或刷新设计,还可能需要再设计更新后,重新编译所有脚本。

这种重用实际上是囿于Lotus Notes架构的不理想的模式。为此,Lotus Notes理论上也提出了解决方案——单一副本模版。数据库的设计继承自这种模版时,只会为每个设计元素生成一个链接到原始设计元素的引用,用到某个设计元素时,Lotus Notes会依据这个引用自动获得模版里的设计元素。如果为这个数据库建一个副本或拷贝,Notes则会将引用替换成实际的设计元素,以免这个新的数据库所在的环境没有单一副本模版。

听起来似乎很理想,实际应用时由于Lotus Notes的特性和场景的制约还需要额外的注意。我们知道Notes客户端有良好高效的缓存机制。打开某个服务器上的应用时,Notes客户端会把初次读取到的设计元素,如表单、视图、代理等,缓存到desktop8.ndk文件(不同版本的缓存文件的名称稍有不同),也可以用“工作台属性”查看和压缩这个文件。下次再用到这个设计元素时,Notes就会直接使用缓存中的版本,省去读取服务器上的数据库。直到关闭这个数据库时,此次会话结束,缓存失效。下次再打开同一个数据库时重新从远程数据库下载和缓存设计元素。这个机制和单一副本模版珠联璧合。如果服务器上的多个数据库继承自位于同一服务器的一个单一副本模版,我们修改了这个模版里的某个表单或代理,所有引用了它们的数据库在用户下次打开时都会自动使用最新的版本。

但这样的场景和实际环境仍然有差距。我们在以前提到过,正式服务器通常不会允许开发人员直接修改其上的数据库的设计,这样刚才所述的自动更新就失去了前提。如果是在本地开发环境下,原本这样做是可行而且有效的。但是Notes客户端对本地数据库的设计元素的缓存似乎另有途径,在模版被修改后,即使退出再重新进入继承它的数据库,看到的仍然是旧的设计元素,除非关闭Notes客户端重新打开,更新才见生效。另一种方法则是模版修改后,手工再次刷新继承它的数据库的设计。

并且,单一副本模版里的LotusScript修改后,继承此模版的数据库仍然很可能需要重新编译脚本才能避免前面讨论的错误,而在“重新编译所有LotusScript”的过程中,为了保存编译后的代码,Notes会将原来引用设计元素的链接先替换成元素实体,这样情况又变得和继承普通模版一样,单一副本模版里的修改再也不能直接反映到继承它的数据库。要恢复单一副本模板的本意,只有对继承设计的数据库再次刷新设计。

所以能够有效应用单一副本模版的场景就像Lotus Notes帮助中作为例子提出的大量设计稳定不变的邮箱继承一个单一副本的邮箱模版,以节省大量重复的设计元素占用的空间。

52. 模版和设计元素——Lotus Notes的代码重用的更多相关文章

  1. 55. 略谈Lotus Notes的与众不同及系列文章至此的总结

    在二十多年的悠久历史里,Lotus Notes发展出一整套独特的概念.技术和思维.由于它早期惊人的领先时代和后续发展中同样惊人的忠于传统,这位软件领域的寿星在如今发展更新速度远超往日和技术愈趋公开互通 ...

  2. Lotus Notes 学习笔记

    这是一个学习关于如何使用Lotus Notes的Agent功能来实现自动化办公的学习笔记. 一. 介绍 Lotus Notes/Domino 是一个世界领先的企业级通讯.协同工作及Internet/I ...

  3. 使用LotusScript操作Lotus Notes RTF域

    Lotus Notes RTF域的功能也非常强大,除了支持普通的文本以外,还支持图片.表格.嵌入对象.Http 链接.Notes 链接.附件等等众多的类型.本文将介绍如何使用这些类来灵活操作富文本域. ...

  4. View模版的设计

    一个Action多套View模版的设计   回到目录 模块化 这个问题是在做模块化设计时出现的,在Lind.DDD.Plugins模块里,需要对应的模块实体,模块管理者,模块标识接口等,开发时,如果你 ...

  5. Lotus Notes中编程发送邮件(二)

    在编程发送各种类似通知的邮件时,时常会需要发件人显示为某个特定的帐户,比如某个部门的名称或者管理员的名字.另一种需求是,用户收到某封邮件后,回复邮件的地址不同于发件人栏显示的地址.而正常情况下,发送邮 ...

  6. C# Windows Service调用IBM Lotus Notes发送邮件

    近日研究了下IBM Lotus Mail,这货果然是麻烦,由于公司策略,没有开放smtp,很多系统邮件都没有办法发送,于是入手google学习Lotus Mail,想做成Windows服务,提供wcf ...

  7. 46. Lotus Notes中编程发送邮件(一)

    邮件是Lotus Notes体系的核心和基本功能,以至于Send()是NotesDocument的一个方法,任何一个文档都可以被发送出去,Notes里的一封邮件也只是一个有一些特殊字段的文档.在程序开 ...

  8. 【Lotus Notes】邮件获取

    public class LotusManager { public static int bodyMaxLength, length; public static List<Entity.Lo ...

  9. C# 使用 Lotus notes 公共邮箱发送邮件

    公司的邮件系统用的是反人类的 Lotus notes, 你敢信? 最近要实现一个功能,邮件提醒功能,就是通过自动发送提醒邮件 前前后后这个问题搞了2天,由于公司的诸多条件限制,无法直接调用到公司发送邮 ...

随机推荐

  1. iOS开发之理解iOS中的MVC设计模式

    模型-视图-控制器(Model-View-Controller,MVC)是Xerox PARC在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已广泛应用于用户交互应用程 ...

  2. Web Deploy发布网站一条龙解决方案

    Web Deploy工具对于ASP.NET开发人员来说一定不陌生,没有用过也经常见到,Web Deploy发布十分方便而且在发布时会帮助用户检验发布文件的正确性.接下来介绍一下基础使用. 第一步:安装 ...

  3. BZOJ 1858: [Scoi2010]序列操作( 线段树 )

    略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...

  4. PHP面向对象基础实例

    <?phpclass marine{ public $blood = 50; //剩余的血 public $kills = 0; //杀敌数量 static $all_num = 0;//兵的数 ...

  5. php 学习笔记 数组2

    10.切割数组 array_slice(array, offset, length);返回一个由原始数组中的连续元素组成的新数组,参数1为原始数组,参数2为要复制的起始位置, 参数3要复制的个数:新数 ...

  6. HDU 5119 Happy Matt Friends(2014北京区域赛现场赛H题 裸背包DP)

    虽然是一道还是算简单的DP,甚至不用滚动数组也能AC,数据量不算很大. 对于N个数,每个数只存在两个状态,取 和 不取. 容易得出状态转移方程: dp[i][j] = dp[i - 1][j ^ a[ ...

  7. svn笔记4属性Properties

    我们已经详细讲述了Subversion存储和检索版本库中不同版本的文件和目录的细节,并且用了好几个章节来论述这个工具的基本功能.如果对于版本化的支持到此为止,从版本控制的角度来看Subversion已 ...

  8. hibernate 一对多映射

    package com.entity.onetomany; import java.util.ArrayList; import java.util.List; import javax.persis ...

  9. WPF Multi-Touch 开发:基础触屏操作(Raw Touch)

    原文 WPF Multi-Touch 开发:基础触屏操作(Raw Touch) 多点触控(Multi-Touch)就是通过与触屏设备的接触达到人与应用程序交互的操作过程.例如,生活中经常使用的触屏手机 ...

  10. CSS:重量和级联规则,确定其优先级

    资源:http://www.ido321.com/1063.html 首先,给大家看一篇关于CSS优先级的演示样例:http://www.ido321.com/76.html 一.主要的优先级规则 比 ...