Sample Application

[Previous] [Next]

I have enhanced the off-line banking system sample application (BSTAM Banker) from the Object By Value design pattern (Chapter 6) to include the Repository design pattern. To summarize, the BSTAM Banker allows bank customers to perform an extensive list of banking services (such as depositing and withdrawing funds and checking the balance) against their accounts off-line. The benefits are mainly optimal system performance without the loss of functionality. Why shouldn't you have your cake and eat it too? In the Chapter 6 sample, customer savings accounts are maintained in a Scripting.Dictionary object by the BankSvr.Teller object. This requires the Teller object to have intimate knowledge about how to manipulate the Dictionary object. What if later you decide to store the accounts in a Sybase database? The Teller object's implementation would have to be rewritten using an appropriate Sybase database API.

Let's say, for example, you decide to use ADO. Manipulating data using ADO is not even remotely similar to using a Dictionary object. Sounds like a big change? Well it is. To remove from the business object layer the responsibility, complexity, and limitations associated with data manipulation in a specific type of data store, in this example I've replaced the Dictionary object with an implementation of the Repository design pattern. Since the SavingsAccount objects are persistable, half the design pattern is already implemented. All that is required is a Repository object. Hence this sample is an ideal fit. Finally, a new feature not found in the BSTAM Banker example in Chapter 6 has been added to allow a customer to update his or her account with the changes made off-line. Account updates are ultimately stored in the Repository referenced by the Teller object. Since BSTAM Banker is already explained in great detail in Chapter 6, here I'll concentrate solely on the Repository design pattern implementation. For a complete source code disclosure, refer to the companion CD.

The key participants of the sample that make up the Repository design pattern include the following:

  • SavingsAccount (resides in AccountLib.DLL) A concrete class that is persistable because its Instancing property value is set to MultiUse, its Persistable property value is set to Persistable, and it implements behavior for reading and writing its state to a byte array data stream by implementing the ReadProperties and WriteProperties class event handlers and by utilizing the PropertyBag object, as shown in the following code extract.
  •  Private Sub Class_ReadProperties(PropBag As PropertyBag) ' Read in property values from a byte array via 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 PropertyBag ' object. With PropBag .WriteProperty "AccountNumber", m_strAccountNo .WriteProperty "AccountOwner", m_strAccountOwner .WriteProperty "InterestRate", m_dblInterestRate .WriteProperty "AccountBalance", m_dblBalance End With End Sub 

  • Repository (resides in RepoLib.DLL) An interface that defines the methods for maintaining an object's state in a data store.
  •  ' Class Name: Repository ' Note: Repository interface that defines the methods for ' storing and retrieving a persistable object to and ' from an underlying data store ' Option Explicit Public Function Add(PID As String, Obj As Object) As Boolean End Function Public Function Update(PID As String, Obj As Object) _ As Boolean End Function Public Function Remove(PID As String) As Boolean End Function Public Function Retrieve(PID As String) As Object End Function 

  • InMemRepository (resides in RepoLib.DLL) Concrete Repository class that implements the methods of the Repository interface for maintaining the state of persistable objects in an in-memory data store. A persistable object's state is stored in the form of a byte array inside a PropertyBag object. The repository must initiate the persistable object to read and write its state to and from a PropertyBag object. (Refer to the "Implementation" section of Chapter 6 for in-depth coverage on the PropertyBag.) The Transformer class defined in the Chapter 6 sample already provides this functionality, so instead of rewriting the code I've reused the Transformer. If a Transformer class wasn't already available, we would add the code shown in the comment directly above the calls to the Transformer object.
  •  ' Class Name: InMemRepository ' Note: A concrete class that implements an in-memory data ' store using a Scripting.Dictionary object ' Implements Repository Private m_ObjectStates As Scripting.Dictionary ' Declared in the Globals.bas file. ' Transformer facilitates the persistence of an object's ' state to a byte array data stream stored in a PropertyBag ' object, which is explained in complete detail in the ' Implementation section of Chapter 6. Public g_Transformer As ObjTransformLib.Transformer  Private Function Repository_Add(PID As String, _ Obj As Object) As Boolean ' Adds a persistable object's state to the data store. Dim byteArr() As Byte If Not m_ObjectStates.Exists(PID) Then ' This code must be implemented if you don't ' use the Transformer class from Chapter 6. ' ' Dim pb As PropertyBag ' Set pb = New PropertyBag ' pb.WriteProperty PID, obj ' byteArr = pb.Contents byteArr = g_Transformer.ObjectToStream(PID, Obj) m_ObjectStates.Add PID, byteArr Repository_Add = True Else Repository_Add = False End If End Function  Private Function Repository_Retrieve(PID As String) _ As Object ' Creates a persistable object, reinitializes its state from ' the data store, and returns a reference to the object Dim vTemp As Variant Dim byteArr() As Byte If m_ObjectStates.Exists(PID) Then vTemp = m_ObjectStates(PID) byteArr = vTemp ' This code must be implemented if you don't ' use the Transformer class from Chapter 6. ' ' Dim pb As PropertyBag ' Set pb = New PropertyBag ' pb.Contents = byteArr ' Set Repository_Retrieve = pb.ReadProperty(PID) Set Repository_Retrieve = g_Transformer _ .StreamToObject(PID, byteArr) Else Set Repository_Retrieve = Nothing End If End Function  

  • Teller (resides in BankSvr.EXE) The Repository design pattern is put to use by the Teller object. SavingsAccount persistable objects are added to the in-memory repository upon construction of the Teller object via its Class_Initialize method:
  •  ' Teller.cls ' Private Sub Class_Initialize() Dim sa As AccountLib.SavingsAccount Dim bRetcode As Boolean ' Declared as a member variable in Declarations section ' Private m_ObjectRep As RepoLib.Repository ' Construct in-memory repository Set m_ObjectRep = New RepoLib.InMemRepository ' Construct and initialize SavingsAccount objects, and ' store in in-memory repository. ' Maxwell Orion's account Set sa = New AccountLib.SavingsAccount With sa .AccountNumber = "orion0425" .AccountOwner = "Maxwell Orion" .InterestRate = 0.039 .Deposit 30000# End With ' Add Maxwell's savings account object to in-memory ' repository. bRetcode = m_ObjectRep.Add(sa.AccountNumber, sa)  

    When a client requests a savings account, the Teller object retrieves the savings account object from the in-memory repository.

     ' Teller.cls ' Public Function RetrieveAccount(AcctNo As String, ...) _ As Boolean Dim sa As AccountLib.SavingsAccount ' Declared as a member variable in Declarations section ' Private m_ObjectRep As RepoLib.Repository ' Retrieve a SavingsAccount object from the ' SavingsAccount object repository (m_ObjectRep). Set sa = Nothing Set sa = m_ObjectRep.Retrieve(AcctNo)  

    When a client updates a savings account, the Teller object stores the state of the savings account object to the in-memory repository:

     ' Teller.cls ' Public Function UpdateAccount(AcctNo As String, ...) _ As Boolean Dim sa As AccountLib.SavingsAccount ' Declared as a member variable in Declarations section ' Private m_ObjectRep As RepoLib.Repository  UpdateAccount = m_ObjectRep.Update(AcctNo, sa) End Function 



Microsoft Visual Basic Design Patterns
Microsoft Visual Basic Design Patterns (Microsoft Professional Series)
ISBN: B00006L567
EAN: N/A
Year: 2000
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net