In order to demonstrate the applicability of the Object By Value design pattern, I have created a sample offline banking system called the BSTAM Banker. It effectively allows bank customers to perform various actions against their accounts off line without having to sacrifice functionality for performance. The user will receive an almost instant reply to all banking services for any type of request (e.g., deposit funds, withdraw funds). This application only permits downloading an account for offline use; in a complete system you could expect the capability to update your bank account by uploading changes back to the bank's computer system. The performance costs of the entire transaction would be significantly less than if the customer were making the transaction on line. With offline banking, all account changes are submitted in a single transmission, while with online banking, every service request results in a remote transmission in both directions—one for the request and the other for the reply from the object providing the service.
You might ask, "How is offline banking implemented in the BSTAM Banker?" Answer: using the Object By Value design pattern. BSTAM Banker contains four major components: BankSvr.EXE, BankClient.EXE, Account-Lib.DLL, and ObjTransformLib.DLL.
When the bank customer clicks the Retrieve Account button in the BSTAM Banker GUI to download a savings account, the following sequence of events, illustrated in Figure 6-4, occurs to allow BankClient to obtain a SavingsAccount object by value from BankSvr.
Private Sub cmdRetrieveAcct_Click() Dim byteArr() As Byte Dim bRetCode As Boolean Dim strPrompt As String strPrompt = "Enter one of the following accounts: " _ & vbNewLine _ & "orion0425, spencer0220, or matthew0316" m_strAcctNo = InputBox(strPrompt, _ "BSTAM Banker - Retrieve Account") ' Obtain a copy of a SavingsAccount object in the form ' of a byte array from the cross-process BankSvr COM ' server. bRetCode = m_Teller.RetrieveAccount(m_strAcctNo, _ byteArr) |
Public Function RetrieveAccount(AcctNo As String, _ ByteArr() As Byte) As Boolean ' Locate and return SavingsAccount object by value to ' caller. Dim sa As AccountLib.SavingsAccount ' Locate a SavingsAccount object in the SavingsAccount ' Dictionary object (m_SavingsAccounts), and transform ' it to a byte array that is returned to the caller. If m_SavingsAccounts.Exists(AcctNo) Then Set sa = m_SavingsAccounts(AcctNo) ByteArr = m_Transformer.ObjectToStream(AcctNo, sa) RetrieveAccount = True Else |
Private Sub cmdRetrieveAcct_Click() ' Transform byte array into a local copy of the ' SavingsAccount from the out-process. Set m_SavingsAcct = m_Transformer.StreamToObject( _ m_strAcctNo, byteArr) |
Figure 6-4. Object diagram of the BSTAM Banker sample application that illustrates passing a SavingsAccount object by value from BankSvr to BankClient.
The key participants of this sample application that make up the Object By Value design pattern include the following:
Private Sub Class_ReadProperties(PropBag As PropertyBag) ' Read in property values from a byte array via the ' PropertyBag object. With PropBag m_strAccountNo = .ReadProperty("AccountNumber") m_strAccountOwner = .ReadProperty("AccountOwner") m_dblInterestRate = .ReadProperty("InterestRate") m_dblBalance = .ReadProperty("AccountBalance") End With End Sub Private Sub Class_WriteProperties(PropBag As PropertyBag) ' Write out property values to a byte array via the ' PropertyBag object. With PropBag .WriteProperty "AccountNumber", m_strAccountNo .WriteProperty "AccountOwner", m_strAccountOwner .WriteProperty "InterestRate", m_dblInterestRate .WriteProperty "AccountBalance", m_dblBalance End With End Sub |
Refer to the companion CD for the complete source code.