The Bank Program

The Process

The use of abstract factories is very straight forward, but it is best to walk through a few functions to see how the various aspects of the application class are used. Let's look at the function that adds an account.

Before we can complete this function we must sketch the parts an look to see where information is needed. At first it seems like we will be able to pop up the Account dialog which has all of the information and allow the user to select the type of account then enter other information. This won't work, since there is no way to ensure that the account will be chosen first. If it isn't we cannot enable the interest dispersion button before the user choses the method of dispersion.

As a result of this we require that the type of account be chosen before the information about the account is gathered. We need to pass the account (actually a pointer to the account) to the Account dialog, so we have the enablers available. This adds a parameter to the constructor we build.

void MainWindow::cmAddAccount ()
{
    // INSERT>> Your code here.
    // Determine the type of the account
    AccountTypeDlgXfer tb;
    Array choices;
    choices = Account::getKinds();
    // A Listbox displays the various types of accounts. This list is initialized
    // from a list kept in the Account dll.
    ArrayIterator next(choices);
    while (next)
    {
        tb._types.AddString(next().c_str());
        next++;
     }
    tb._types.Select(0);
    if (AccountTypeDlg(&tb,this).Execute()==IDOK )
    {
        //Use the factory to create the account
        AcctPtr newAcct = Account::create(tb._types.GetSelIndex());
        AccountDlgXfer actb;
        //Should be a virtual function to create this number for each type of account
        strcpy(actb._number,"123");
        actb._balance[0]='\0';
        actb._name[0]='\0';
        actb._ssnumber[0] ='\0';
        strcpy(actb._type,Account::getKindString(tb._types.GetSelIndex()).c_str());
        strcpy(actb._dispersal,Account::getDispersalString(0).c_str());
       // After initializing the AccountDlg transfer buffer, gather account information
        if (AccountDlg(&actb,newAcct,this).Execute()==IDOK)
        {
            char buff[255];
            double bal=atof(actb._balance);
            newAcct->setValues(actb._name,actb._ssnumber,actb._number,newAcct->getDispersal(),bal);
            _accounts.insertItem(newAcct);
            newAcct->printString(buff);
            _acctListBox->AddString(buff);
      }
     }
}

The only button that is enabled is the dispersal method button. We use the enable function from the class to determine if the button is enabled for this type of account. Note the dialog enabler must be called from the dialogs SetupWindow function. It is only called once, since an account either allows this to change or doesn't.

void AccountDlg::changeBNDisable ()
{
    // INSERT>> Your code here.
    _changeButton->EnableWindow(_acct->interestDispersal());
}


void AccountDlg::SetupWindow ()
{
    TDialog::SetupWindow();

    // INSERT>> Your code here.
    changeBNDisable();
}

The integer value used to store the method of interest dispersal are determined by the Dispersal dialog, while the Account dialog only displays a readonly text version. Since the account needs to know the integer value, and this value is only available in the account dialog, we set this value locally. An alternative to this would be to make the Account dialog resizable. If an account allows interest dispersal choice the dialog is resized to show a combo box with these choices.

void AccountDlg::changeDispersal ()
{
   // INSERT>> Your code here.
    DispersalDlgXfer tb;
    Array choices;
    choices = Account::getDispersals();
    ArrayIterator next(choices);
    while (next)
    {
        tb._types.AddString(next().c_str());
        next++;
    }
    tb._types.Select(0);
    if (DispersalDlg(&tb,this).Execute())
    {
        int which = tb._types.GetSelIndex();
        _acct->setDispersal(which);
        _dispersal->SetText(choices[which].c_str());
    }
}

Complete Code

For the complete code for the bank problem click here.

Back to Week 9.