52. 模版和设计元素——Lotus Notes的代码重用
不论是理论上还是实用上,代码重用都是编程的一个重要议题。可以从两个角度来讨论代码重用。
一是逻辑上代码以怎样的方式被重用。既可以通过面向对象的思想普及以来耳熟能详的继承的方式。比如先建了一个车的基类,再从它衍生出轿车、卡车、大客车等子类,基类车的功能就被这些子类重用了。另一种途径是从函数被发明起就一直被使用的组合。例如我们已经有了轱辘、轴、车斗、木杆等部件,就可以组合出一辆三轮车。
第二个角度是实体上代码以怎样的方式被重用。从需要连接的静态库文件、可以动态加载的库到直接引用的脚本文件,都有各自的特点。
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的代码重用的更多相关文章
- 55. 略谈Lotus Notes的与众不同及系列文章至此的总结
在二十多年的悠久历史里,Lotus Notes发展出一整套独特的概念.技术和思维.由于它早期惊人的领先时代和后续发展中同样惊人的忠于传统,这位软件领域的寿星在如今发展更新速度远超往日和技术愈趋公开互通 ...
- Lotus Notes 学习笔记
这是一个学习关于如何使用Lotus Notes的Agent功能来实现自动化办公的学习笔记. 一. 介绍 Lotus Notes/Domino 是一个世界领先的企业级通讯.协同工作及Internet/I ...
- 使用LotusScript操作Lotus Notes RTF域
Lotus Notes RTF域的功能也非常强大,除了支持普通的文本以外,还支持图片.表格.嵌入对象.Http 链接.Notes 链接.附件等等众多的类型.本文将介绍如何使用这些类来灵活操作富文本域. ...
- View模版的设计
一个Action多套View模版的设计 回到目录 模块化 这个问题是在做模块化设计时出现的,在Lind.DDD.Plugins模块里,需要对应的模块实体,模块管理者,模块标识接口等,开发时,如果你 ...
- Lotus Notes中编程发送邮件(二)
在编程发送各种类似通知的邮件时,时常会需要发件人显示为某个特定的帐户,比如某个部门的名称或者管理员的名字.另一种需求是,用户收到某封邮件后,回复邮件的地址不同于发件人栏显示的地址.而正常情况下,发送邮 ...
- C# Windows Service调用IBM Lotus Notes发送邮件
近日研究了下IBM Lotus Mail,这货果然是麻烦,由于公司策略,没有开放smtp,很多系统邮件都没有办法发送,于是入手google学习Lotus Mail,想做成Windows服务,提供wcf ...
- 46. Lotus Notes中编程发送邮件(一)
邮件是Lotus Notes体系的核心和基本功能,以至于Send()是NotesDocument的一个方法,任何一个文档都可以被发送出去,Notes里的一封邮件也只是一个有一些特殊字段的文档.在程序开 ...
- 【Lotus Notes】邮件获取
public class LotusManager { public static int bodyMaxLength, length; public static List<Entity.Lo ...
- C# 使用 Lotus notes 公共邮箱发送邮件
公司的邮件系统用的是反人类的 Lotus notes, 你敢信? 最近要实现一个功能,邮件提醒功能,就是通过自动发送提醒邮件 前前后后这个问题搞了2天,由于公司的诸多条件限制,无法直接调用到公司发送邮 ...
随机推荐
- ThinkPHP - 登录流程
数据库: /* Navicat MySQL Data Transfer Source Server : 本地连接 Source Server Version : 50710 Source Host : ...
- ubuntu中在线升级python
sudo add-apt-repository ppa:fkrull/deadsnakes-python2.7 sudo apt-get update sudo apt-get upgrade 笔记
- Python框架 Flask 项目实战教程
本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深.最好对着源码,一步一步走.下载源码,运行pip install -r requirements.txt 建立环境python db_ ...
- Altera FPGA中的pin进一步说明
最近END china上的大神阿昏豆发表了博文 <FPGA研发之道(25)-管脚>,刚好今天拿到了新书<深入理解Altera FPGA应用设计>第一章开篇就讲pin.这里就两者 ...
- Core dotnet 命令大全
Core dotnet 命令大全 dotnet 命令大全,让你理解dotnet 命令. 本文将以一个实例串起 dotnet 所有命令,让你玩转dotnet 命令. 本篇文章编写环境为windows 1 ...
- 登陆整合实现-QQ互联认证(ASP.NET版本)
原文:登陆整合实现-QQ互联认证(ASP.NET版本) 首先 我们创建一个qq.ashx的页面,这个页面会跳转到QQ的请求界面 代码如下: QQSettingConfig qqSettingConfi ...
- Eclipse下执行main函数报java.lang.NoClassDefFoundError的解决
今天执行eclipse下的一个java类,无论run还是debug,都报java.lang.NoClassDefFoundError.而且把main中函数都注释掉,执行还是报一样的错. 检查了一下这个 ...
- 学习MongoDB 二:MongoDB加入、删除、改动
一.简单介绍 MongoDB是一个高性能.开源.无模式的文档型数据库,是当前NoSQL数据库产品中最热门的一种.数据被分组存储在数据集中,被称为一个集合(Collenction)和对于存储在Mongo ...
- GCD基本使用
主要概念 队列 dispatch_queue_t,队列名称在调试时辅助,无论什么队列和任务,线程的创建和回收不需要程序员操作,有队列负责. 串行队列:队列中的任务只会顺序执行(类似跑步) dispat ...
- Inter IPP的一些基本类型对应的vs中类型
来自为知笔记(Wiz)