📄 ch08.htm
字号:
<TT> 37: </TT><TT> 38: // Destructor.</TT><TT> 39: ATMCardImpl::~ATMCardImpl() {</TT><TT> 40: </TT><TT> 41: }</TT><TT> 42: </TT><TT> 43: CORBA::Short ATMCardImpl::pin() {</TT><TT> 44: </TT><TT> 45: return myPIN;</TT><TT> 46: }</TT><TT> 47: </TT><TT> 48: void ATMCardImpl::pin(CORBA::Short val) {</TT><TT> 49: </TT><TT> 50: myPIN = val;</TT><TT> 51: }</TT><TT> 52: </TT><TT> 53: CORBA::Boolean ATMCardImpl::isAuthorized(Account_ptr account) {</TT><TT> 54: </TT><TT> 55: std::vector<Account_ptr>::iterator first = myAccounts.begin();</TT><TT> 56: std::vector<Account_ptr>::iterator last = myAccounts.end();</TT><TT> 57: IsAccountEqual predicate(account);</TT><TT> 58: </TT><TT> 59: std::vector<Account_ptr>::iterator matchedAccount = std::</TT><TT> 60: find_if(first, last, predicate);</TT><TT> 61: if (matchedAccount == last) {</TT><TT> 62: </TT><TT> 63: // Account not found; return false.</TT><TT> 64: return 0;</TT><TT> 65: } else {</TT><TT> 66: </TT><TT> 67: // Account found; return true.</TT><TT> 68: return 1;</TT><TT> 69: }</TT><TT> 70: }</TT><TT> 71: </TT><TT> 72: void ATMCardImpl::removeAccount(Account_ptr account) throw</TT><TT> 73: (InvalidAccountException) {</TT><TT> 74: </TT><TT> 75: if (!isAuthorized(account)) {</TT><TT> 76: </TT><TT> 77: // Invalid Account; throw an exception.</TT><TT> 78: throw InvalidAccountException();</TT><TT> 79: }</TT><TT> 80: </TT><TT> 81: // Delete the given Account.</TT><TT> 82: myAccounts.erase(&account);</TT><TT> 83: account->_release();</TT><TT> 84: }</TT><TT> 85: </TT><TT> 86: void ATMCardImpl::addAccount(Account_ptr account) throw</TT><TT> 87: (InvalidAccountException) {</TT><TT> 88: </TT><TT> 89: if (isAuthorized(account)) {</TT><TT> 90: </TT><TT> 91: // Account has already been added, so throw an exception.</TT><TT> 92: throw InvalidAccountException();</TT><TT> 93: }</TT><TT> 94: </TT><TT> 95: // Add the created Account at the end of the list.</TT><TT> 96: myAccounts.push_back(Account::_duplicate(account));</TT><TT> 97: }</TT><TT> 98: </TT><TT> 99: AccountList* ATMCardImpl::getAccounts() {</TT><TT>100: </TT><TT>101: AccountList* list = new AccountList(myAccounts.size());</TT><TT>102: CORBA::Long i;</TT><TT>103: </TT><TT>104: for (i = 0; i < myAccounts.size(); i++) {</TT><TT>105: (*list)[i] = Account::_duplicate(myAccounts[i]);</TT><TT>106: }</TT><TT>107: </TT><TT>108: return list;109: }</TT> </FONT></PRE><P>Because nothing different needs to be done when a <TT>BankImpl</TT> object iscreated, no changes are necessary from the original <TT>BankMain.cpp</TT>, but, forgood measure, it appears in Listing 8.12.<H4><FONT COLOR="#000077">Listing 8.12. BankMain.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankMain.cpp</TT><TT> 2: </TT><TT> 3: #include "BankImpl.h"</TT><TT> 4: </TT><TT> 5: #include <iostream.h></TT><TT> 6: </TT><TT> 7: #include "../BankServer_c.h"</TT><TT> 8: </TT><TT> 9: CORBA::BOA_var boa;</TT><TT>10: </TT><TT>11: int main(int argc, char *const *argv) {</TT><TT>12: </TT><TT>13: // Check the number of arguments; there should be exactly one</TT><TT>14: // (two counting the executable name itself).</TT><TT>15: if (argc != 2) {</TT><TT>16: cout << "Usage: Bank <bankname>" << endl;</TT><TT>17: return 1;</TT><TT>18: }</TT><TT>19: </TT><TT>20: // Assign the bank name to the first argument.</TT><TT>21: const char* bankName = argv[1];</TT><TT>22: </TT><TT>23: // Initialize the ORB and BOA.</TT><TT>24: CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);</TT><TT>25: ::boa = orb->BOA_init(argc, argv);</TT><TT>26: </TT><TT>27: // Create a Bank object.</TT><TT>28: BankImpl bank(bankName);</TT><TT>29: </TT><TT>30: // Notify the BOA that the BankImpl object is ready.</TT><TT>31: ::boa->obj_is_ready(&bank);</TT><TT>32: </TT><TT>33: // Locate a BankServer object and register with it.</TT><TT>34: BankServer_var bankServer;</TT><TT>35: try {</TT><TT>36: bankServer = BankServer::_bind();</TT><TT>37: } catch (const CORBA::Exception& ex) {</TT><TT>38: </TT><TT>39: // The bind attempt failed...</TT><TT>40: cout << "BankImpl: Unable to bind to a BankServer." << endl;</TT><TT>41: cout << ex << endl;</TT><TT>42: return 1;</TT><TT>43: }</TT><TT>44: try {</TT><TT>45: bankServer->registerBank(&bank);</TT><TT>46: } catch (const CORBA::Exception& ex) {</TT><TT>47: </TT><TT>48: // The registerBank() attempt failed...</TT><TT>49: cout << "BankImpl: Unable to register Bank." << endl;</TT><TT>50: cout << ex << endl;</TT><TT>51: return 1;</TT><TT>52: }</TT><TT>53: </TT><TT>54: // Wait for CORBA events.</TT><TT>55: cout << "Bank \"" << bankName << "\" ready." << endl;</TT><TT>56: ::boa->impl_is_ready();</TT><TT>57: </TT><TT>58: // When this point is reached, the application is finished.</TT><TT>59: return 0;60: }</TT></FONT></PRE><H3><A NAME="Heading10"></A><FONT COLOR="#000077">Implementing the ATM Server</FONT></H3><P>The implementation of <TT>ATMImpl</TT> (see Listings 8.13 and 8.14) is clear-cut.The <TT>ATMImpl</TT> simply forwards requests to withdraw funds into an <TT>Account</TT>,to deposit funds into an <TT>Account</TT>, and to get the current balance of an <TT>Account</TT>.Each operation uses the <TT>ATMCard</TT> to authorize the transaction, and if the<TT>ATMCard</TT> approves, the transaction is forwarded to the <TT>Account</TT>.Because the transaction itself is performed by the <TT>Account</TT>, the implementationsfor <TT>withdraw()</TT>, <TT>deposit()</TT>, and <TT>getBalance()</TT> are simple.<H4><FONT COLOR="#000077">Listing 8.13. ATMImpl.h.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // ATMImpl.h</TT><TT> 2: </TT><TT> 3: #ifndef ATMImpl_h</TT><TT> 4: #define ATMImpl_h</TT><TT> 5: </TT><TT> 6: #include "../ATM_s.h"</TT><TT> 7: </TT><TT> 8: class ATMImpl : public _sk_ATM {</TT><TT> 9: </TT><TT>10: public:</TT><TT>11: // Constuctor.</TT><TT>12: //</TT><TT>13: // name - the name of this ATM.</TT><TT>14: ATMImpl(const char* name);</TT><TT>15: </TT><TT>16: // Destructor.</TT><TT>17: ~ATMImpl();</TT><TT>18: </TT><TT>19: // These methods are described in ATM.idl.</TT><TT>20: virtual char* name();</TT><TT>21: virtual void name(const char* val);</TT><TT>22: virtual CORBA::Float withdraw(ATMCard_ptr card, Account_ptr</TT><TT>23: account, CORBA::Short pin, CORBA::Float amount) throw</TT><TT>24: (AuthorizationException, InvalidAmountException,</TT><TT>25: InsufficientFundsException);</TT><TT>26: virtual CORBA::Float deposit(ATMCard_ptr card, Account_ptr</TT><TT>27: account, CORBA::Short pin, CORBA::Float amount) throw</TT><TT>28: (AuthorizationException, InvalidAmountException);</TT><TT>29: virtual CORBA::Float getBalance(ATMCard_ptr card, Account_ptr</TT><TT>30: account, CORBA::Short pin) throw</TT><TT>31: (AuthorizationException);</TT><TT>32: </TT><TT>33: private:</TT><TT>34: </TT><TT>35: // Default constuctor.</TT><TT>36: ATMImpl();</TT><TT>37: </TT><TT>38: // This ATM's name.</TT><TT>39: char* myName;</TT><TT>40: };</TT><TT>41: 42: #endif</TT></FONT></PRE><H4><FONT COLOR="#000077">Listing 8.14. ATMImpl.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // ATMImpl.cpp</TT><TT> 2: </TT><TT> 3: #include "ATMImpl.h"</TT><TT> 4: </TT><TT> 5: #include <iostream.h></TT><TT> 6: </TT><TT> 7: // Constuctor.</TT><TT> 8: //</TT><TT> 9: // name - the name of this ATM.</TT><TT>10: ATMImpl::ATMImpl(const char* name) : _sk_ATM(name),</TT><TT>11: myName(strdup(name)) {</TT><TT>12: </TT><TT>13: }</TT><TT>14: </TT><TT>15: // Default constuctor.</TT><TT>16: ATMImpl::ATMImpl() : _sk_ATM(""), myName(NULL) {</TT><TT>17: </TT><TT>18: }</TT><TT>19: </TT><TT>20: // Destructor.</TT><TT>21: ATMImpl::~ATMImpl() {</TT><TT>22: </TT><TT>23: free(myName);</TT><TT>24: }</TT><TT>25: </TT><TT>26: char* ATMImpl::name() {</TT><TT>27: </TT><TT>28: return CORBA::strdup(myName);</TT><TT>29: }</TT><TT>30: </TT><TT>31: void ATMImpl::name(const char* val) {</TT><TT>32: </TT><TT>33: free(myName);</TT><TT>34: myName = strdup(val);</TT><TT>35: }</TT><TT>36: </TT><TT>37: CORBA::Float ATMImpl::withdraw(ATMCard_ptr card, Account_ptr</TT><TT>38: account, CORBA::Short pin, CORBA::Float amount) throw</TT><TT>39: (AuthorizationException, InvalidAmountException,</TT><TT>40: InsufficientFundsException) {</TT><TT>41: </TT><TT>42: cout << "ATM: Authorizing Account for withdrawal." << endl;</TT><TT>43: if (pin != card->pin() || !card->isAuthorized(account)) {</TT><TT>44: </TT><TT>45: // Incorrect PIN or card not authorized; throw an</TT><TT>46: // exception.</TT><TT>47: cout << " Authorization failed." << endl;</TT><TT>48: throw AuthorizationException();</TT><TT>49: }</TT><TT>50: </TT><TT>51: cout << " Authorization succeeded; forwarding withdrawal " <<</TT><TT>52: "request to Account." << endl;</TT><TT>53: return account->withdraw(amount);</TT><TT>54: }</TT><TT>55: </TT><TT>56: CORBA::Float ATMImpl::deposit(ATMCard_ptr card, Account_ptr</TT><TT>57: account, CORBA::Short pin, CORBA::Float amount) throw</TT><TT>58: (AuthorizationException, InvalidAmountException) {</TT><TT>59: </TT><TT>60: cout << "ATM: Authorizing Account for deposit." << endl;</TT><TT>61: if (pin != card->pin() || !card->isAuthorized(account)) {</TT><TT>62: </TT><TT>63: // Incorrect PIN or card not authorized; throw an</TT><TT>64: // exception.</TT><TT>65: cout << " Authorization failed." << endl;</TT><TT>66: throw AuthorizationException();</TT><TT>67: }</TT><TT>68: </TT><TT>69: cout << " Authorization succeeded; forwarding deposit " <<</TT><TT>70: "request to Account." << endl;</TT><TT>71: return account->deposit(amount);</TT><TT>72: }</TT><TT>73: </TT><TT>74: CORBA::Float ATMImpl::getBalance(ATMCard_ptr card, Account_ptr</TT><TT>75: account, CORBA::Short pin) throw (AuthorizationException) {</TT><TT>76: </TT><TT>77: cout << "ATM: Authorizing Account for balance." << endl;</TT><TT>78: if (pin != card->pin() || !card->isAuthorized(account)) {</TT><TT>79: </TT><TT>80: // Incorrect PIN or card not authorized; throw an</TT><TT>81: // exception.</TT><TT>82: cout << " Authorization failed." << endl;</TT><TT>83: throw AuthorizationException();</TT><TT>84: }</TT><TT>85: </TT><TT>86: cout << " Authorization succeeded; forwarding balance " <<</TT><TT>87: "request to Account." << endl;</TT><TT>88: return account->balance();89: }</TT> </FONT></PRE><P>Again, the implementation in <TT>ATMMain.cpp</TT> is one that can be mostly borrowedfrom somewhere else. In this case, because an <TT>ATM</TT> interacts with the <TT>BankServer</TT>much the same way as a <TT>Bank</TT> does, you can borrow the code from <TT>BankMain.cpp</TT>and m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -