用vfp建立3層客戶服務(wù)器程序

字號:

應(yīng)用程序開發(fā)的一個(gè)偉大的事實(shí)是:對于每一件事情都可用多種方法來完成.建造應(yīng)用程序時(shí)的最困難的事情是選擇一種方法及確定它是否比其它的方法更好. 在客戶服務(wù)器開發(fā)中,這種情況是你是在用兩種數(shù)據(jù)庫引擎進(jìn)行處理, Visual FoxPro 在前端而一個(gè)強(qiáng)有力的 SQL 數(shù)據(jù)庫引擎在后端.
    《整合 SQL Server 和 Visual FoxPro》一文探索了用 SQL pass-through. 創(chuàng)建兩層客戶服務(wù)器程序. 在本文中,用Visual FoxPro建立一個(gè) OLE 服務(wù)器用于創(chuàng)建三層客戶服務(wù)器程序. 添加一個(gè)中間層,給你以額外的地方來放置代碼和執(zhí)行驗(yàn)證.
    胖客戶問題
    客戶服務(wù)器應(yīng)用程序開發(fā)者如何分離地處理前端和后端的困境是眾所周知的. Visual FoxPro 和 SQL Server 兩者都具有非常有力的數(shù)據(jù)庫引擎. 兩者都有有力的編程語言并有能力驗(yàn)證數(shù)據(jù)和強(qiáng)制商業(yè)規(guī)則.
    近來有很多關(guān)于工業(yè)上的胖客戶和瘦客戶以及它們對客戶服務(wù)器應(yīng)用程序開發(fā)的影響. 作為可用的前端開發(fā)工具已發(fā)展成熟,并有越來越依賴它們的傾向. 后端的負(fù)擔(dān)并不輕,但也會造成問題.
    載入前端的第一個(gè)問題是需要一個(gè)更為有力的計(jì)算機(jī). 當(dāng)然如果你使用 Visual FoxPro 作為后端你可能需要至少 486 和 12 MB 內(nèi)存. 這個(gè)問題是術(shù)語"胖客戶"是如何產(chǎn)生的. 如果你正在選擇要使用的后端,前端是當(dāng)然要考慮的. 你會權(quán)衡 Visual FoxPro, Visual Basic, Access, Delphi, PowerBuilder, Java 以及其它所有編程語言的優(yōu)缺點(diǎn)和資源需求. Java 是動人的,因?yàn)樗峁┱嬲膿碛凶銐蚰芰Φ氖菘蛻羟岸顺兄Z. Visual FoxPro 5.0 值得注目地比 3.0 減肥.
    前端執(zhí)行大量處理的第二個(gè)問題是假如你的驗(yàn)證和商業(yè)規(guī)則發(fā)生變化你必須修改在前后中的代碼. 這可能是或不是一個(gè)問題. 假設(shè)你正在開發(fā) Visual FoxPro 前端, 你也要發(fā)生對 SQL Server 后端的修改. 如果你是驗(yàn)證和商業(yè)規(guī)則代碼的編寫者, 你大概會只寫一次, 用 Visual FoxPro 或 SQL Server 儲存過程或兩者的組合. 如果某些方法必須修改,而你是修改者, 很大的問題的代碼位于什么地方?
    在另一方面, 你可能編寫前端而不寫后端. 你可能不被允許編寫你自己的 Select, Insert, Update 和Delete. 后端管理人可能限制你只能使用儲存過程. 這種方法的好處是保證前端的正確執(zhí)行. 如果只允許你通過儲存過程訪問數(shù)據(jù), 你將被迫按正確的順序執(zhí)行. 例如, 如果你刪除一個(gè)成員則不能忘記刪除該成員的預(yù)約. 如果你添加一個(gè)新成員則不能忘記放入新的 ID 到 Adult 表中.
    如果你的前端只是一系列訪問相同后端的前端的一個(gè)又會怎么樣呢? 在這種情況下你會想要所有邏輯在后端上發(fā)生. 那種方法, 如果要進(jìn)行任何修改,只需要修改一個(gè)地方.
    三層體系
    客戶服務(wù)器開發(fā)最近的一個(gè)進(jìn)步是三層體系方案. 傳統(tǒng)的客戶服務(wù)器是兩層的, 由一個(gè)客戶和一個(gè)服務(wù)器組成. 正如上面的討論,如果太多的處理集中在客戶或服務(wù)器上, 可能會有潛在的問題. 三層體系引入一個(gè)中間層, 用于減輕兩端的負(fù)擔(dān).
    在一個(gè)典型的三層體系中, 如下表所示, 各層負(fù)責(zé)提供一個(gè)服務(wù). 客戶提供用戶服務(wù), 它主要由用戶界面組成. 服務(wù)器提供數(shù)據(jù)服務(wù), 由數(shù)據(jù)和維護(hù)訪問方法組成. 中間層提供商業(yè)服務(wù), 由數(shù)據(jù)驗(yàn)證和強(qiáng)制商業(yè)方法組成
    表1: 分層應(yīng)用程序體系
    要充分認(rèn)識到該結(jié)構(gòu)的潛力, 你應(yīng)該使中間層易于訪問多個(gè)前端. 如果它強(qiáng)制你規(guī)則,則所有客戶需要與它交談. 不管客戶是用 Visual FoxPro,Visual Basic 還是其它語言寫成,這都是事實(shí).
    中間層將會運(yùn)行于不同的機(jī)器上. 這允許它可被多個(gè)客戶訪問,而且它提供性能. 記住, 胖客戶問題是客戶機(jī)器負(fù)擔(dān)過重. 在一個(gè)兩層結(jié)構(gòu)中你可能必須為每一個(gè)客戶提供 16 MB (功更多) 內(nèi)存的 Pentium 機(jī)器. 在一個(gè)三層結(jié)構(gòu)中你可以將中間層放在一個(gè) 32 MB 雙處理器 Pentium 機(jī)器,并愉快地在 12 MB 內(nèi)存的486 機(jī)器上運(yùn)行客戶程序.
    至少可以用兩種方法來設(shè)置中間層. 一種方法是用一個(gè) SQL Server 機(jī)器作為服務(wù)器和中間層. 本文中使用的方法是使用一個(gè)在 Visual FoxPro 中創(chuàng)建的 OLE server 作為中間層. OLE server 從 Visual FoxPro 中調(diào)用, 或?qū)τ谌魏?OLE 控制器, 使用 CreateObject() 函數(shù), 與你調(diào)用 Excel 或 Word 作為 OLE Automation 服務(wù)器一樣.
    創(chuàng)建Visual FoxPro OLE 服務(wù)程序
    如果你還不知道如何在 Visual FoxPro 中創(chuàng)建一個(gè) OLE 服務(wù)器請參閱《Visual FoxPro 作為 OLE Automation Servers》 和《自定義 OLE Servers》. 你也可以從 Visual FoxPro 聯(lián)機(jī)幫助文檔中 (Visual FoxPro 開發(fā)指南第十六章)知道如何做.
    在 Win32 的世界中, OLE 服務(wù)器可以作為 InProc 或 OutOfProc 服務(wù)器創(chuàng)建(Windows 95 和 Windows NT) ,它是一個(gè)運(yùn)行應(yīng)用程序的處理并可以尋址到 4 GB 的內(nèi)存, 一半是用于保存處理代碼,另一半是系統(tǒng)使用. InProc 服務(wù)器是編譯成 DLL 并運(yùn)行在調(diào)用它的過程的相同的地址空間. OutOfProc 服務(wù)器是編譯成 EXE 文件并作為單獨(dú)的過程運(yùn)行. InProc 服務(wù)器可提供司長能,因?yàn)檫^程中通信比內(nèi)部通信慢. 在另一方面, 由于 OutOfProc 服務(wù)器運(yùn)行在一個(gè)單獨(dú)的過程中,你可以利用多處理器的優(yōu)勢.
    OLE 服務(wù)器也可在本地或遠(yuǎn)程運(yùn)行. 典型地一個(gè)遠(yuǎn)程 OLE 服務(wù)器是一個(gè) OutOfProc 服務(wù)器并位于超級計(jì)算機(jī)上. 這允許任意多個(gè)客戶機(jī)器訪問它. Remote Automation Connection Manager 可用于配置服務(wù)器和客戶機(jī)器來允許遠(yuǎn)程自動控制.
    示例數(shù)據(jù)
    本文使用的示例數(shù)據(jù)是來自于 SQL Server 6.5 的圖書館應(yīng)用程序. 圖書館應(yīng)用程序想要保持對其成員、圖書和借閱的跟蹤.
    表結(jié)構(gòu)
    圖書館應(yīng)用程序中的主要表之一是 Member 表, 圖書館中的每一位成員在其中有一條記錄. 這里一個(gè)有趣的手法是少年必須要有成年人擔(dān)保才能成為圖書館成員. 大概由于少年會在相同的地方成長為成年人, 因此有兩個(gè)單獨(dú)的表 Adult(成年) 和 Juvenile(少年). 這樣節(jié)約了磁盤空間,因?yàn)橐坏阒懒顺扇说牡刂穭t所有少年的地址信息是多余的. 另外, 少年的期滿日期與成人相同. 進(jìn)一步說, 你不用在意成人的出生日期,你只需注意少年的出生日期及何時(shí)滿18 歲變?yōu)槌扇?至少在表中要反映出來!).
    以下代碼顯示了用于創(chuàng)建 Member, Adult 和 Juvenile 表的SQL Server 語句:
    CREATE TABLE member
    ( member_no member_no NOT NULL identity(1,1),
    lastname shortstring NOT NULL ,
    firstname shortstring NOT NULL ,
    middleinitial letter NULL ,
    photograph IMAGE NULL )
    CREATE TABLE adult
    ( member_no member_no NOT NULL ,
    street shortstring NOT NULL ,
    city shortstring NOT NULL ,
    state statecode NOT NULL ,
    zip zipcode NOT NULL ,
    phone_no phonenumber NULL ,
    expr_date DATETIME NOT NULL )
    CREATE TABLE juvenile
    ( member_no member_no NOT NULL ,
    adult_member_no member_no NOT NULL ,
    birth_date DATETIME NOT NULL )
    Member 表中的 member_no 字段在添加新記錄時(shí)會由 SQL Server 自動生成。該字段是一個(gè) Identity 列。起始值為 1 ,增量值也是 1。這樣在表中輸入的第一條記錄的 member_no 值就是 1。對于后來插入到表中的記錄 member_no 的值自動增加 1。當(dāng)添加一條記錄時(shí)如果客戶沒有指定 member_no 的值。SQL Server 自動維護(hù)它并詢問客戶使用什么值。
    在 Adult 和 Juvenile 表中的 member_no 不是 Identity 列。這些記錄中的值必須與 Member 表中相應(yīng)的 member_no 值相匹配。當(dāng)新記錄添加到圖書館庫時(shí),一個(gè)記錄首先會添加到 Member 表中。SQL Server 的全局變量 @@Identity 包含了自動生成的 member_no。然后添加到 Adult 或 Juvenile 表中的記錄的 member_no 值將使用 @@Identity 中的值。
    定義參照完整性
    在早期版本的 SQL Server 參照完整性是通過使用觸發(fā)器強(qiáng)制執(zhí)行,這與 Visual FoxPro 強(qiáng)制參照完整性相同。SQL Server 6.0 添加了可申明的參照完整性,這允許你定義你自己的作為數(shù)據(jù)結(jié)構(gòu)一部分的參照完整性規(guī)則。第一步是在各表中創(chuàng)建基本關(guān)鍵字約束,如以下代碼所示:
    ALTER TABLE member
    ADD constraint member_ident PRIMARY KEY clustered
    (member_no)
    ALTER TABLE adult
    ADD constraint adult_ident PRIMARY KEY clustered
    (member_no)
    ALTER TABLE juvenile
    ADD constraint juvenile_ident PRIMARY KEY clustered
    (member_no)
    基本關(guān)鍵字約束創(chuàng)建一個(gè)索引,用于強(qiáng)制 member_no 的性。在示例中創(chuàng)建一組索引用于對數(shù)據(jù)進(jìn)行物理排序。
    定義可申明的參照完整性的第二步是在相關(guān)表之間創(chuàng)建外部關(guān)鍵字約束,如以下代碼所示:
    ALTER TABLE adult
    ADD CONSTRAINT adult_member_link FOREIGN KEY (member_no)
    REFERENCES member (member_no)
    ALTER TABLE juvenile
    ADD CONSTRAINT juvenile_member_link FOREIGN KEY
    (member_no) REFERENCES member (member_no)
    ALTER TABLE juvenile
    ADD CONSTRAINT juvenile_adult_link FOREIGN KEY
    (adult_member_no) REFERENCES adult (member_no)
    第一個(gè) Alter Table 定義了一個(gè) Member 和 Adult 表之間的關(guān)系。這是一個(gè)一對一關(guān)系,雖然這里沒有代碼指明或強(qiáng)制是這種類型的關(guān)系。第二個(gè) Alter Table 在 Member 和 Juvenile 表部定義了一個(gè)關(guān)系。最后一個(gè) Alter Table 在 Adult 和 Juvenile 表之間定義一個(gè)關(guān)系。這是一個(gè)一對多關(guān)系。
    要意識到 SQL Server 當(dāng)前不支持級聯(lián)更新或刪除。如果你想那樣做就應(yīng)該用觸發(fā)器代替約束。
    圖書館 OLE 服務(wù)程序使用 SQL pass-through 來與 SQL Server 圖書館數(shù)據(jù)庫交談. 服務(wù)器將包含采取行動(如獲取一個(gè)成員的信息,添加一個(gè)新成員修改成員的信息和刪除一個(gè)成員)的方法. 服務(wù)器提供少量的屬性, 包括發(fā)生了何種錯誤的屬性.
    OLE 服務(wù)程序項(xiàng)目是 LIBRARYSERVER.PJX. 該項(xiàng)目包含一個(gè)自定義類叫做Members. 該類已被識別為OLE Public (要這樣做,在類信息對話框中復(fù)選適當(dāng)?shù)膹?fù)選項(xiàng)).
    Members 類的成員和屬性, 分別在表1 和 表 2中列出.
    方法 可視度 描述
    InitConnection 公共 初始化與SQL Server 的連接
    CloseConnection 公共 關(guān)閉與SQL Server 的連接
    GetMember 公共 接收一個(gè)成員的信息
    AddMember 公共 添加一個(gè)新成員
    UpdateMember 公共 更新一個(gè)成員的信息
    RemoveMember 公共 移除一個(gè)成員
    SetError 受保護(hù) 保存 SQL Server 錯誤
    Convert 受保護(hù) 轉(zhuǎn)換值到串
    表 2: 圖書館 OLE 服務(wù)程序?qū)傩?BR>    屬性 可視度 描述
    NHandle 公共 連接句柄
    NewID 公共 新添加的成員的ID
    LastErrDesc 公共 最后出現(xiàn)的錯誤的描述
    在圖3顯示的項(xiàng)目信息對話框中, 項(xiàng)目的名稱為 VFPLibraryOLEServer. 結(jié)合類名 Members, 就產(chǎn)生了OLE 名稱 VFPLibraryOLEServer.Members. 這可以在注冊表的 HKEY_CLASSES_ROOT 中找到, 如圖4所示.
    OLE 服務(wù)程序是在生成時(shí)自動注冊到機(jī)器上. 如果你把它移動到另一臺機(jī)器上可以用 REGSVR32.EXE 注冊它, REGSVR32.EXE 可以在 Windows 95 下的 System 目錄和 Windows NT 下的 System32 目錄中找到.
    要在客戶應(yīng)用程序上使用 OLE 服務(wù)程序,應(yīng)使用下面這樣的代碼.
    oLibrary = CreateObject("VFPLibraryOLEServer.Members")
    當(dāng) Visual FoxPro 遇到該代碼時(shí)它首先檢查對象名是否是一個(gè) Visual FoxPro 類. 如果不是, 則檢查注冊表. 當(dāng)找到對象名和對象的標(biāo)識符 CLSID, is noted.
    也是在注冊表的 HKEY_CLASSES_ROOT 中有一個(gè)名為 CLSID 的鍵值, 它包含一個(gè)所有具有 CLSID 的對象的入口. 就象你在圖5中看到的一樣, 注冊表保存著與可執(zhí)行文件相關(guān)的 CLSID. 這就是為什么當(dāng) Visual FoxPro 執(zhí)行它的 CreateObject 命令時(shí) Windows 知道如何啟動 OLE 服務(wù)程序.
    使用圖書館 OLE 服務(wù)程序
    表單 MEMBOLEFP.SCX 使用 Visual FoxPro 圖書館OLE 服務(wù)程序作為中間層來與 SQL Server 圖書館數(shù)據(jù)庫圖書館. 在調(diào)用服務(wù)程序后表單調(diào)用方法來獲取成員信息, 刪除和更新成員等.