📄 ch09.htm
字号:
new <TT>requestUpdateService()</TT> method. Also, notice that the <TT>InvalidAccountException</TT>comes into play again here, in case an <TT>Account</TT> is passed that does not belongto the <TT>Bank</TT>.</P><P>The other changes are made to <TT>Customer.idl</TT>, which appears in Listing9.2.<H4><FONT COLOR="#000077">Listing 9.2. Modified Customer.idl.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // Customer.idl</TT><TT> 2: </TT><TT> 3: // Forward declaration of Customer interface.</TT><TT> 4: interface Customer;</TT><TT> 5: </TT><TT> 6: #ifndef Customer_idl</TT><TT> 7: #define Customer_idl</TT><TT> 8: </TT><TT> 9: // sequence of Customers</TT><TT>10: typedef sequence<Customer> CustomerList;</TT><TT>11: </TT><TT>12: #include "Account.idl"</TT><TT>13: </TT><TT>14: // A Customer can hold one or more Accounts. Presumably, the</TT><TT>15: // Customer is what drives the rest of this application.</TT><TT>16: interface Customer {</TT><TT>17: </TT><TT>18: // This Customer's name.</TT><TT>19: attribute string name;</TT><TT>20: </TT><TT>21: // This Customer's Social Security number.</TT><TT>22: readonly attribute string socialSecurityNumber;</TT><TT>23: </TT><TT>24: // This Customer's address.</TT><TT>25: attribute string address;</TT><TT>26: </TT><TT>27: // This Customer's mother's maiden name.</TT><TT>28: readonly attribute string mothersMaidenName;</TT><TT>29: </TT><TT>30: // Return a list of Accounts held (or co-held) by this</TT><TT>31: // Customer.</TT><TT>32: AccountList getAccounts();</TT><TT>33: </TT><B><TT>34: // Send an update message to this Customer regarding the given</TT></B><B><TT>35: // Account and its new balance.</TT></B><B><TT>36: oneway void updateAccountBalance(in Account account, in float</TT></B><B><TT>37: balance);</TT></B><TT>38: };</TT><TT>39: 40: #endif</TT> </FONT></PRE><P>Again, changes to <TT>Customer.idl</TT> are minimal, adding only the <TT>updateAccountBalance()</TT>method. Note the use of the <TT>oneway</TT> modifier, indicating that when this methodis called, it will return to the caller immediately.</P><P>You're now ready to proceed with the changes to the implementation itself.<H2><A NAME="Heading5"></A><FONT COLOR="#000077">Implementing the New Functionality</FONT></H2><P>Implementing the account update functionality is also a simple process. Giventhat only two methods have been added to the entire system, there are only a coupleof steps involved:<UL> <LI>Implement <TT>requestUpdateService()</TT> in the <TT>BankImpl</TT> class. The <TT>BankImpl</TT> must keep track of all <TT>Account</TT>s for which the service is activated; when it comes time to send update messages to the <TT>Account</TT>s' <TT>Customer</TT>s, the <TT>BankImpl</TT> can simply traverse this list of <TT>Account</TT>s.<BR> <BR> <LI>Implement <TT>updateAccountBalance()</TT> in the <TT>CustomerImpl</TT> class. This method can be as trivial as simply printing a message indicating the <TT>Account</TT> and its new balance.</UL><H3><A NAME="Heading6"></A><FONT COLOR="#000077">Enhancing the BankImpl</FONT></H3><P>First, you'll modify <TT>BankImpl</TT> to provide the <TT>requestUpdateService()</TT>functionality. As already mentioned, the <TT>BankImpl</TT> must maintain a list of<TT>Account</TT>s for which the automatic update service is activated. You'll seehow this is done in Listing 9.3, <TT>BankImpl.h</TT>, with changes highlighted in<B>bold.</B><H4><FONT COLOR="#000077">Listing 9.3. BankImpl.h.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankImpl.h</TT><TT> 2: </TT><TT> 3: #ifndef BankImpl_h</TT><TT> 4: #define BankImpl_h</TT><TT> 5: </TT><TT> 6: #include <vector></TT><TT> 7: </TT><TT> 8: #include "../Bank_s.h"</TT><TT> 9: </TT><TT>10: class BankImpl : public _sk_Bank {</TT><TT>11: </TT><TT>12: public:</TT><TT>13: </TT><TT>14: // Constructor.</TT><TT>15: //</TT><TT>16: // name - This Bank's name.</TT><TT>17: BankImpl(const char* name);</TT><TT>18: </TT><TT>19: // Destructor.</TT><TT>20: ~BankImpl();</TT><TT>21: </TT><TT>22: // These methods are described in Bank.idl.</TT><TT>23: virtual char* name();</TT><TT>24: virtual void name(const char* val);</TT><TT>25: virtual char* address();</TT><TT>26: virtual void address(const char* val);</TT><TT>27: virtual Account_ptr createAccount(Customer_ptr customer,</TT><TT>28: const char* accountType, CORBA::Float openingBalance);</TT><TT>29: virtual void deleteAccount(Account_ptr account) throw</TT><TT>30: (InvalidAccountException);</TT><TT>31: virtual AccountList* getAccounts();</TT><TT>32: virtual ATMCard_ptr issueATMCard(CORBA::Short pin, Account_ptr</TT><TT>33: account) throw (InvalidAccountException);</TT><B><TT>34: virtual void requestUpdateService(Account_ptr account) throw</TT></B><B><TT>35: (InvalidAccountException);</TT></B><TT>36: </TT><TT>37: protected:</TT><TT>38: </TT><TT>39: // Return the next available account number. The result is</TT><TT>40: // returned in a static buffer.</TT><TT>41: char* getNextAccountNumber();</TT><TT>42: </TT><TT>43: // Return the current date in the form "Mmm DD YYYY". The result</TT><TT>44: // is returned in a static buffer.</TT><TT>45: char* getCurrentDate();</TT><TT>46: </TT><TT>47: private:</TT><TT>48: </TT><TT>49: // Default constructor.</TT><TT>50: BankImpl();</TT><TT>51: </TT><TT>52: // This Bank's name.</TT><TT>53: char* myName;</TT><TT>54: </TT><TT>55: // This Bank's address.</TT><TT>56: char* myAddress;</TT><TT>57: </TT><TT>58: // This Bank's Accounts.</TT><TT>59: std::vector<Account_ptr> myAccounts;</TT><TT>60: </TT><B><TT>61: // The Accounts which are subscribed to the automatic update</TT></B><B><TT>62: // service.</TT></B><B><TT>63: std::vector<Account_ptr> mySubscribedAccounts;</TT></B><TT>64: </TT><TT>65: // The next available account number.</TT><TT>66: unsigned int myNextAccountNumber;</TT><TT>67: };</TT><TT>68: 69: #endif</TT> </FONT></PRE><P>In <TT>BankImpl.h</TT>, note the addition of the <TT>requestUpdateService()</TT>method and the <TT>mySubscribedAccounts</TT> data member. <TT>mySubscribedAccounts</TT>is a C++ Standard Template Library <TT>vector</TT>, just like the <TT>myAccounts</TT>member, which contains all the <TT>Account</TT>s held by a particular <TT>Bank</TT>.In Listing 9.4,<TT> BankImpl.cpp</TT>, you'll observe how the elements of <TT>mySubscribedAccounts</TT>are managed.<H4><FONT COLOR="#000077">Listing 9.4. BankImpl.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankImpl.cpp</TT><TT> 2: </TT><TT> 3: #include "BankImpl.h"</TT><TT> 4: </TT><B><TT> 5: #include <process.h></TT></B><TT> 6: </TT><TT> 7: #include <time.h></TT><TT> 8: #include <string.h></TT><TT> 9: #include <iostream.h></TT><TT> 10: #include <algorithm></TT><TT> 11: #include <functional></TT><TT> 12: </TT><TT> 13: #include "SavingsAccountImpl.h"</TT><TT> 14: #include "CheckingAccountImpl.h"</TT><TT> 15: #include "ATMCardImpl.h"</TT><TT> 16: </TT><TT> 17: extern CORBA::BOA_var boa;</TT><TT> 18: </TT><TT> 19: // STL-derived unary function which returns TRUE if Accounts are</TT><TT> 20: // equal.</TT><TT> 21: class IsAccountEqual : public std::unary_function<Account_ptr,</TT><TT> 22: bool> {</TT><TT> 23: public:</TT><TT> 24: IsAccountEqual(argument_type account) { myAccount = account; }</TT><TT> 25: result_type operator()(argument_type account) { return account-></TT><TT> 26: _is_equivalent(myAccount) != 0; }</TT><TT> 27: private:</TT><TT> 28: argument_type myAccount;</TT><TT> 29: };</TT><TT> 30: </TT><B><TT> 31: void updateAccountThreadFunction(LPVOID pParam) {</TT></B><B><TT> 32: </TT></B><B><TT> 33: std::vector<Account_ptr>* accounts = (std::</TT></B><B><TT> 34: vector<Account_ptr>*)pParam;</TT></B><B><TT> 35: </TT></B><B><TT> 36: while (1) {</TT></B><B><TT> 37: Sleep(60000);</TT></B><B><TT> 38: cout << "BankImpl: Updating Accounts." << endl;</TT></B><B><TT> 39: </TT></B><B><TT> 40: // Iterate through the list of Accounts.</TT></B><B><TT> 41: for (int i = 0; i < accounts->size(); i++) {</TT></B><B><TT> 42: </TT></B><B><TT> 43: // For each Account, get the list of Customers and send</TT></B><B><TT> 44: // an update message to each.</TT></B><B><TT> 45: CustomerList* customers = (*accounts)[i]-></TT></B><B><TT> 46: getCustomers();</TT></B><B><TT> 47: for (CORBA::Long j = 0; j < customers->length(); j++) {</TT></B><B><TT> 48: try {</TT></B><B><TT> 49: (*customers)[i]-></TT></B><B><TT> 50: updateAccountBalance((*accounts)[i],</TT></B><B><TT> 51: (*accounts)[i]->balance());</TT></B><B><TT> 52: } catch (const CORBA::Exception&) {</TT></B><B><TT> 53: </TT></B><B><TT> 54: // Ignore the exception; we don't care if</TT></B><B><TT> 55: // there's a problem with the update.</TT></B><B><TT> 56: }</TT></B><B><TT> 57: }</TT></B><B><TT> 58: }</TT></B><B><TT> 59: }</TT></B><B><TT> 60: }</TT></B><TT> 61: </TT><TT> 62: // Constructor.</TT><TT> 63: //</TT><TT> 64: // name - This Bank's name.</TT><TT> 65: BankImpl::BankImpl(const char* name) : _sk_Bank(name), myAccounts(),</TT><TT> 66: <B>mySubscribedAccounts(),</B> myName(strdup(name)),</TT><TT> 67: myAddress(strdup("123 Elm Street, Anywhere USA 12345")),</TT><TT> 68: myNextAccountNumber(0) {</TT><TT> 69: </TT><B><TT> 70: _beginthread(&updateAccountThreadFunction, 0,</TT></B><B><TT> 71: &mySubscribedAccounts);</TT></B><TT> 72: }</TT><TT> 73: </TT><TT> 74: // Default constructor.</TT><TT> 75: BankImpl::BankImpl() : myAccounts(), <B>mySubscribedAccounts(),</B></TT><TT> 76: myName(NULL), myAddress(NULL), myNextAccountNumber(0) {</TT><TT> 77: </TT><TT> 78: }</TT><TT> 79: </TT><TT> 80: // Destructor.</TT><TT> 81: BankImpl::~BankImpl() {</TT><TT> 82: </TT><TT> 83: cout << "Bank \"" << name() << "\" being destroyed." << endl;</TT><TT> 84: free(myName);</TT><TT> 85: free(myAddress);</TT><TT> 86: }</TT><TT> 87: </TT><TT> 88: char* BankImpl::name() {</TT><TT> 89: </TT><TT> 90: return CORBA::strdup(myName);</TT><TT> 91: }</TT><TT> 92: </TT><TT> 93: void BankImpl::name(const char* val) {</TT><TT> 94: </TT><TT> 95: free(myName);</TT><TT> 96: myName = strdup(val);</TT><TT> 97: }</TT><TT> 98: </TT><TT> 99: char* BankImpl::address() {</TT><TT>100: </TT><TT>101: return CORBA::strdup(myAddress);</TT><TT>102: }</TT><TT>103: </TT><TT>104: void BankImpl::address(const char* val) {</TT><TT>105: </TT><TT>106: free(myAddress);</TT><TT>107: myAddress = strdup(val);</TT><TT>108: }</TT><TT>109: </TT><TT>110: Account_ptr BankImpl::createAccount(Customer_ptr customer,</TT><TT>111: const char* accountType, CORBA::Float openingBalance) {</TT><TT>112: </TT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -