📄 ch08.htm
字号:
<TT>35: BankServerImpl();</TT><TT>36: </TT><TT>37: // This BankServer's list of Banks.</TT><TT>38: std::vector<Bank_ptr> myBanks;</TT><TT>39: </TT><B><TT>40: // This BankServer's list of ATMs.</TT></B><B><TT>41: std::vector<ATM_ptr> myATMs;</TT></B><TT>42: };</TT><TT>43: 44: #endif</TT> </FONT></PRE><P>In Listing 8.5, note the similarity between the <TT>registerBank()</TT> method(lines 21-22) and the <TT>registerATM()</TT> method (lines 26-27), as well as theother pairs of corresponding methods. Also, just as the <TT>BankServerImpl</TT> usesa <TT>std::vector<Bank_ptr></TT> to store references to <TT>Bank</TT> objects(as seen in lines 37-38), it now uses a <TT>std::vector<ATM_ptr></TT> to storereferences to <TT>ATM</TT> objects (lines 40-41).</P><P>Listing 8.6 illustrates the further similarities between the previously existingmethod implementations in <TT>BankServerImpl</TT> and the <TT>ATM</TT>-related methodsbeing added. The implementations are exactly the same, with references to <TT>Bank</TT>schanged to references to <TT>ATM</TT>s, and so on. (Because the semantics of theoperations are the same for <TT>ATM</TT>s as for <TT>Bank</TT>s, it isn't surprisingthat the implementations are nearly identical.)<H4><FONT COLOR="#000077">Listing 8.6. BankServerImpl.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankServerImpl.cpp</TT><TT> 2: </TT><TT> 3: #include "BankServerImpl.h"</TT><TT> 4: </TT><TT> 5: #include <algorithm></TT><TT> 6: #include <functional></TT><TT> 7: </TT><TT> 8: // STL-derived unary function which returns TRUE if Banks are equal.</TT><TT> 9: class IsBankEqual : public std::unary_function<Bank_ptr, bool> {</TT><TT> 10: public:</TT><TT> 11: IsBankEqual(argument_type bank) { myBank = bank; }</TT><TT> 12: result_type operator()(argument_type bank) { return bank-></TT><TT> 13: _is_equivalent(myBank) != 0; }</TT><TT> 14: private:</TT><TT> 15: argument_type myBank;</TT><TT> 16: };</TT><TT> 17: </TT><B><TT> 18: // STL-derived unary function which returns TRUE if ATMs are equal.</TT></B><B><TT> 19: class IsATMEqual : public std::unary_function<ATM_ptr, bool> {</TT></B><B><TT> 20: public:</TT></B><B><TT> 21: IsATMEqual(argument_type atm) { myATM = atm; }</TT></B><B><TT> 22: result_type operator()(argument_type atm) { return atm-></TT></B><B><TT> 23: _is_equivalent(myATM) != 0; }</TT></B><B><TT> 24: private:</TT></B><B><TT> 25: argument_type myATM;</TT></B><B><TT> 26: };</TT></B><TT> 27: </TT><TT> 28: // Constructor.</TT><TT> 29: BankServerImpl::BankServerImpl(const char* name) :</TT><TT> 30: _sk_BankServer(name), myBanks()<B>,</B> myATMs() {</TT><TT> 31: </TT><TT> 32: }</TT><TT> 33: </TT><TT> 34: // Destructor.</TT><TT> 35: BankServerImpl::~BankServerImpl() {</TT><TT> 36: </TT><TT> 37: }</TT><TT> 38: </TT><TT> 39: void BankServerImpl::registerBank(Bank_ptr bank) throw</TT><TT> 40: (InvalidBankException) {</TT><TT> 41: </TT><TT> 42: // First, ensure that the given Bank doesn't exist already.</TT><TT> 43: std::vector<Bank_ptr>::iterator first = myBanks.begin();</TT><TT> 44: std::vector<Bank_ptr>::iterator last = myBanks.end();</TT><TT> 45: IsBankEqual predicate(bank);</TT><TT> 46: </TT><TT> 47: std::vector<Bank_ptr>::iterator matchedBank = std::</TT><TT> 48: find_if(first, last, predicate);</TT><TT> 49: if (matchedBank == last) {</TT><TT> 50: </TT><TT> 51: // Bank was not found, so add the given Bank to the end of</TT><TT> 52: // the list.</TT><TT> 53: cout << "BankServerImpl: Registering Bank \"" << bank-></TT><TT> 54: name() << "\"." << endl;</TT><TT> 55: myBanks.push_back(Bank::_duplicate(bank));</TT><TT> 56: return;</TT><TT> 57: } else {</TT><TT> 58: </TT><TT> 59: // The Bank was already registered, so throw an exception.</TT><TT> 60: throw InvalidBankException();</TT><TT> 61: }</TT><TT> 62: }</TT><TT> 63: </TT><TT> 64: void BankServerImpl::unregisterBank(Bank_ptr bank) throw</TT><TT> 65: (InvalidBankException) {</TT><TT> 66: </TT><TT> 67: std::vector<Bank_ptr>::iterator first = myBanks.begin();</TT><TT> 68: std::vector<Bank_ptr>::iterator last = myBanks.end();</TT><TT> 69: IsBankEqual predicate(bank);</TT><TT> 70: </TT><TT> 71: std::vector<Bank_ptr>::iterator matchedBank = std::</TT><TT> 72: find_if(first, last, predicate);</TT><TT> 73: if (matchedBank == last) {</TT><TT> 74: </TT><TT> 75: // Invalid Bank; throw an exception.</TT><TT> 76: cout << "BankServerImpl: Attempted to unregister invalid "</TT><TT> 77: "Bank." << endl;</TT><TT> 78: throw InvalidBankException();</TT><TT> 79: }</TT><TT> 80: cout << "BankServerImpl: Unregistering Bank \"" << bank->name()</TT><TT> 81: << "\"." << endl;</TT><TT> 82: </TT><TT> 83: // Delete the given Bank.</TT><TT> 84: myBanks.erase(matchedBank);</TT><TT> 85: bank->_release();</TT><TT> 86: }</TT><TT> 87: </TT><TT> 88: BankList* BankServerImpl::getBanks() {</TT><TT> 89: </TT><TT> 90: BankList* list = new BankList();</TT><TT> 91: CORBA::Long i;</TT><TT> 92: </TT><TT> 93: list->length(myBanks.size());</TT><TT> 94: for (i = 0; i < myBanks.size(); i++) {</TT><TT> 95: (*list)[i] = Bank::_duplicate(myBanks[i]);</TT><TT> 96: }</TT><TT> 97: </TT><TT> 98: cout << "BankServerImpl: Returning list of " << myBanks.size()</TT><TT> 99: << " Banks." << endl;</TT><TT>100: </TT><TT>101: return BankList::_duplicate(list);</TT><TT>102: }</TT><TT>103: </TT><B><TT>104: void BankServerImpl::registerATM(ATM_ptr atm) throw</TT></B><B><TT>105: (InvalidATMException) {</TT></B><B><TT>106: </TT></B><B><TT>107: // First, ensure that the given ATM doesn't exist already.</TT></B><B><TT>108: std::vector<ATM_ptr>::iterator first = myATMs.begin();</TT></B><B><TT>109: std::vector<ATM_ptr>::iterator last = myATMs.end();</TT></B><B><TT>110: IsATMEqual predicate(atm);</TT></B><B><TT>111: </TT></B><B><TT>112: std::vector<ATM_ptr>::iterator matchedATM = std::find_if(first,</TT></B><B><TT>113: last, predicate);</TT></B><B><TT>114: if (matchedATM == last) {</TT></B><B><TT>115: </TT></B><B><TT>116: // ATM was not found, so add the given ATM to the end of</TT></B><B><TT>117: // the list.</TT></B><B><TT>118: cout << "BankServerImpl: Registering ATM \"" << atm-></TT></B><B><TT>119: name() << "\"." << endl;</TT></B><B><TT>120: myATMs.push_back(ATM::_duplicate(atm));</TT></B><B><TT>121: return;</TT></B><B><TT>122: } else {</TT></B><B><TT>123: </TT></B><B><TT>124: // The ATM was already registered, so throw an exception.</TT></B><B><TT>125: throw InvalidATMException();</TT></B><B><TT>126: }</TT></B><B><TT>127: }</TT></B><B><TT>128: </TT></B><B><TT>129: void BankServerImpl::unregisterATM(ATM_ptr atm) throw</TT></B><B><TT>130: (InvalidBankException) {</TT></B><B><TT>131: </TT></B><B><TT>132: std::vector<ATM_ptr>::iterator first = myATMs.begin();</TT></B><B><TT>133: std::vector<ATM_ptr>::iterator last = myATMs.end();</TT></B><B><TT>134: IsATMEqual predicate(atm);</TT></B><B><TT>135: </TT></B><B><TT>136: std::vector<ATM_ptr>::iterator matchedATM = std::find_if(first,</TT></B><B><TT>137: last, predicate);</TT></B><B><TT>138: if (matchedATM == last) {</TT></B><B><TT>139: </TT></B><B><TT>140: // Invalid ATM; throw an exception..</TT></B><B><TT>141: cout << "BankServerImpl: Attempted to unregister invalid "</TT></B><B><TT>142: "ATM." << endl;</TT></B><B><TT>143: throw InvalidATMException();</TT></B><B><TT>144: }</TT></B><B><TT>145: cout << "BankServerImpl: Unregistering ATM \"" << atm->name()</TT></B><B><TT>146: << "\"." << endl;</TT></B><B><TT>147: </TT></B><B><TT>148: // Delete the given ATM.</TT></B><B><TT>149: myATMs.erase(matchedATM);</TT></B><B><TT>150: atm->_release();</TT></B><B><TT>151: }</TT></B><B><TT>152: </TT></B><B><TT>153: ATMList* BankServerImpl::getATMs() {</TT></B><B><TT>154: </TT></B><B><TT>155: ATMList* list = new ATMList();</TT></B><B><TT>156: CORBA::Long i;</TT></B><B><TT>157: </TT></B><B><TT>158: list->length(myATMs.size());</TT></B><B><TT>159: for (i = 0; i < myATMs.size(); i++) {</TT></B><B><TT>160: (*list)[i] = ATM::_duplicate(myATMs[i]);</TT></B><B><TT>161: }</TT></B><B><TT>162: </TT></B><B><TT>163: cout << "BankServerImpl: Returning list of " << myATMs.size()</TT></B><B><TT>164: << " ATMs." << endl;</TT></B><B><TT>165: </TT></B><B><TT>166: return ATMList::_duplicate(list);167: }</TT></B> </FONT></PRE><P>As shown in Listing 8.7, no changes are necessary to <TT>BankServerMain.cpp</TT>;the <TT>BankServer</TT> application starts up in exactly the same way it did on Day7.<H4><FONT COLOR="#000077">Listing 8.7. BankServerMain.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankServerMain.cpp</TT><TT> 2: </TT><TT> 3: #include "BankServerImpl.h"</TT><TT> 4: #include <iostream.h></TT><TT> 5: </TT><TT> 6: int main(int argc, char *const *argv) {</TT><TT> 7: </TT><TT> 8: // Initialize the ORB and BOA.</TT><TT> 9: CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);</TT><TT>10: CORBA::BOA_var boa = orb->BOA_init(argc, argv);</TT><TT>11: </TT><TT>12: // Create a BankServerImpl object.</TT><TT>13: BankServerImpl bankServer("BankServer");</TT><TT>14: </TT><TT>15: // Notify the BOA that the BankServerImpl object is ready.</TT><TT>16: boa->obj_is_ready(&bankServer);</TT><TT>17: </TT><TT>18: // Wait for CORBA events.</TT><TT>19: cout << "BankServer ready." << endl;</TT><TT>20: boa->impl_is_ready();</TT><TT>21: </TT><TT>22: // When this point is reached, the application is finished.</TT><TT>23: return 0;24: }</TT></FONT></PRE><H3><A NAME="Heading9"></A><FONT COLOR="#000077">Enhancing the Bank</FONT></H3><P>In Listings 8.8 and 8.9, the <TT>BankImpl</TT> class is largely unchanged, exceptfor the addition of <TT>issueATMCard()</TT> in lines 32-33. This method accepts arequest to issue an <TT>ATMCard</TT> for a given <TT>Account</TT>. <TT>issueATMCard()</TT>first checks the <TT>Account</TT> object to see whether it exists in this <TT>Bank</TT>.If it does, the <TT>ATMCard</TT> is issued; if not, an <TT>InvalidAccountException</TT>is thrown.<H4><FONT COLOR="#000077">Listing 8.8. 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><B><TT>32: virtual ATMCard_ptr issueATMCard(CORBA::Short pin, Account_ptr</TT></B><B><TT>33: account) throw (InvalidAccountException);</TT></B><TT>34: </TT><TT>35: protected:</TT><TT>36: </TT><TT>37: // Return the next available account number. The result is</TT><TT>38: // returned in a static buffer.</TT><TT>39: char* getNextAccountNumber();</TT><TT>40: </TT><TT>41: // Return the current date in the form "Mmm DD YYYY". The result</TT><TT>42: // is returned in a static buffer.</TT><TT>43: char* getCurrentDate();</TT><TT>44: </TT><TT>45: private:</TT><TT>46: </TT><TT>47: // Default constructor.</TT><TT>48: BankImpl();</TT><TT>49: </TT><TT>50: // This Bank's name.</TT><TT>51: char* myName;</TT><TT>52: </TT><TT>53: // This Bank's address.</TT><TT>54: char* myAddress;</TT><TT>55: </TT><TT>56: // This Bank's Accounts.</TT><TT>57: std::vector<Account_ptr> myAccounts;</TT><TT>58: </TT><TT>59: // The next available account number.</TT><TT>60: unsigned int myNextAccountNumber;</TT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -