Engine-Collection-Class,一种用来建立可重用企业组件的设计模式[6]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 xxcc 的 blog

public property get account() as object
    on error goto errorhandler
    
    dim engaccount as object
    dim errornum as long
    
    if mcolaccount is nothing then
        if not safecreateobject(engaccount, obp_account_eng, _
            errornum) then
            err.raise err_accountsafecreatefailed, _
                  "iobpuserinfoeng.account property", "unable to " & _
                  "create " & obp_account_eng & ". return code: " & _
                  errornum
            goto cleanexit
        end if
        '只获取未删除的记录(默认条件)。
        set mcolaccount = engaccount.search(securitytoken := _
            securitytoken, usernumber := me.usernumber)
    end if
    set account = mcolaccount
    <...>
end property

再仔细看一下:首先,检查内部变量看当前是否有引用指向 account collection。如果有,则返回此 collection;否则,调用 account engine 的 search 方法来返回与当前的 usernumber 相关联的一个或多个 account。这意味着对于 coluserinfo collection 中的每个 cuserinfo class,都将有一个特定的 account 或多个 account — 对应该单个 usernumber; 换句话说,一个层次结构。此外,在调用 account 方法之前,cuserinfo 中并不存在 account collection,因此实现了按需要加载。因为对 search 方法的内部调用只完成了一次,所以像 refresh 这样的参数可以被添加到该对象的接口中。这就允许动态重新加载内容而无须破坏和重新创建 cuserinfo。这说明构建在 ecc 中的可重用性和层次结构中的松散耦合对象的价值。它还允许以最小的影响更改实现的细节。用户永远不会知道在这个罩盖之下发生的一切。一个样例用户的代码行如下所示:

straccountnumber = coluserinfo.item(1).account.item(1).number

准确了解在此行中发生的情况是重要的。首先,假定您已经创建了一个称为 coluserinfouserinfo collection,其中每个用户至少有一个账户。第一步,coluserinfo.item(1),调用 item 方法并返回与该用户对应的 cuserinfo class。下一步,.account,创建一个 account engine,此 engine 又创建一个 account collection,并向其中置入一个或多个 caccount class,然后返回此 collection。再下一步,.item(1),调用 account collection 的 item 方法,此方法返回第一个 caccount class。最后一步,.number,调用 number property get 方法并返回带有此账户编号的一个字符串,该字符串又被赋给 straccountnumber 变量。

获取一个特性需要做大量的工作,访问该特定对象的每个特性都意味着为所访问的每个特性创建一个 collection 和 class。在这种情况下,将此代码写为如下的形式较好:

      dim colaccounts as colaccount
      
      set colaccounts = userinfo.item(1).account
      straccountcode = colacounts.item(1).number
      strphone = colaccounts.item(1).custphone
      strname = colaccounts.item(1).custname

使用这种方法,就避免了对 userinfoaccount 方法所进行的几个调用的开销。也可能使用一个 for..each 结构。当仅访问一个账户时,可以编写以下的代码:

      dim objaccount as caccount

      set objaccount = userinfo.item(1).account.item(1)
      straccountcode = objaccount.number
      strphone = objaccount.phone
      strname = objaccount.custname

这是非常有效的,并减少了为每个账户属性多次调用 items() 方法的开销。它同样应该提供最佳的性能。

collection 的设计

collection 是 class 对象的容器,也是内部存储方案的包装。大多数面向对象的开发人员,特别是 visual basic 开发人员应该熟悉 collection/class 模型。在 ecc 模型中,collection 的主要责任是:

  • 提供一个存储 class 的容器

  • 将接口与容器的实现细节分开

  • 为操纵容器中的 class 提供服务

  • 保持 class 的信息

  • 连接其它对象来模拟复杂的关系或层次结构(可选

可以用许多不同的方法来实现 collection 的内部存储:数组、链接列表、记录集、xml 或者另一个公用数据存储模型。此处,重要的概念是:实际存储对于高级开发人员是隐藏的,他们总是以相同的方式访问数据,而不管它的存储形式。与 class 一样,collection 的接口和实现也是分开的,这就减少了更改实现带来的影响。

下面讨论一个存储 cuserinfo class 的样例 collection 以及 ecc 设计模式建议的其它特性/方法。visual modeler 用来生成初始图形。

注意:   该对象的前缀 col 表示一个 collection。

每个 class 都有一个单独的 collection,这样就会获得更大的灵活性,因为它允许为 class 适当地定制接口。其中的一个例子便是 add(),它要求传入特定的 userinfo 参数。

图 5. userinfo 实体的基本 collection

对 collection 接口的基本建议,collection 接口提供创建、读取、更新和删除 (crud) 功能,如下所示:

  • addlongpublic function()— 用来根据已定义的参数向 collection 中添加一个新 class。例如,此实现要求新的 userinfo class 在创建一个新 class 之前需要有四个参数。它返回新对象的索引。

    注意:   add() 方法应该将新 class 放在 collection 的尾部,否则现有的索引将失效。它也可以检查此项目是否事先已经存在(特定于实现的)。

  • countlongpublic get()— 用来返回 collection 中 class 的数目。

本文关键:Pattern VB
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top