Describes an iterative process in which design and implementation are repeated
Development methodology that strives for simplicity by removing formal structure and focusing on best practices
class Car extends Vehicle //inheritance "is-a" { ... private Tire[] tires; //instance variable "has-a" }
Relationship
|
Symbol
|
Line Style
|
Arrow tip
|
|
![]() |
|
|
|
![]() |
|
|
|
![]() |
|
|
|
![]() |
|
|
s
Sam's Small Appliances | ||||
100 Main Street | ||||
Anytown, CA 98765 | ||||
Description | Price |
Qty
|
Total | |
Toaster | 29.95 |
3
|
89.85 | |
Hair dryer | 24.95 |
1
|
24.95 | |
Car vacuum | 19.99 |
2
|
39.98 | |
Amount Due: $154.78 |
Invoice
|
format the invoice
|
Address |
add a product and quantity | Item |
Product | |
Address
|
format the address
|
|
Product
|
get description
|
|
get unit price | |
Item
|
format the item
|
Product |
get total price | |
/** Describes an invoice for a set of purchased products. */ class Invoice { /** Adds a charge for a product to this invoice. @param aProduct the product that the customer ordered @param quantity the quantity of the product */ public void add(Product aProduct, int quantity) { } /** Formats the invoice. @return the formatted invoice */ public String format() { } /** Computes the total amount due. @Return the amount due */ public double getAmountDue() { } } /** Describes a quantity an article to purchase and its price. */ Class Item { /** Computes the total cost of this item. @Return the total price */ public double getTotalPrice() { } /** Formats this item. @Return a formatted string of this item */ public String format() { } }
/** Describes a product with a description and a price */ class Product { /** Gets the product description. @Return the description */ public String getDescription() { } /** Gets the product price. @Return the unit price */ public double getPrice() { } } /** Describes a mailing address. */ Class Address { /** Formats the address. @Return the address as a string with 3 lines */ public String format() { } }
1 | import java.util.Vector; |
2 | |
3 | /** |
4 | This program tests the invoice classes by printing |
5 | a sample invoice. |
6 | */ |
7 | public class InvoiceTest |
8 | { |
9 | public static void main(String[] args) |
10 | { |
11 | Address samsAddress |
12 | = new Address("Sam's Small Appliances", |
13 | "100 Main Street", "Anytown", "CA", "98765"); |
14 | |
15 | Invoice samsInvoice = new Invoice(samsAddress); |
16 | samsInvoice.add(new Product("Toaster", 29.95), 3); |
17 | samsInvoice.add(new Product("Hair dryer", 24.95), 1); |
18 | samsInvoice.add(new Product("Car vacuum", 19.99), 2); |
19 | |
20 | System.out.println(samsInvoice.format()); |
21 | } |
22 | } |
23 | |
24 | |
25 |
1 | import java.util.ArrayList; |
2 | |
3 | /** |
4 | Describes an invoice for a set of purchased products. |
5 | */ |
6 | class Invoice |
7 | { |
8 | /** |
9 | Constructs an invoice. |
10 | @param anAddress the billing address |
11 | */ |
12 | public Invoice(Address anAddress) |
13 | { |
14 | items = new ArrayList(); |
15 | billingAddress = anAddress; |
16 | } |
17 | |
18 | /** |
19 | Adds a charge for a product to this invoice. |
20 | @param aProduct the product that the customer ordered |
21 | @param quantity the quantity of the product |
22 | */ |
23 | public void add(Product aProduct, int quantity) |
24 | { |
25 | Item anItem = new Item(aProduct, quantity); |
26 | items.add(anItem); |
27 | } |
28 | |
29 | /** |
30 | Formats the invoice. |
31 | @return the formatted invoice |
32 | */ |
33 | public String format() |
34 | { |
35 | String r = " I N V O I C E\n\n" |
36 | + billingAddress.format() |
37 | + "\n\nDescription Price Qty Total\n"; |
38 | for (int i = 0; i < items.size(); i++) |
39 | { |
40 | Item nextItem = (Item)items.get(i); |
41 | r = r + nextItem.format() + "\n"; |
42 | } |
43 | |
44 | r = r + "\nAMOUNT DUE: $" + getAmountDue(); |
45 | |
46 | return r; |
47 | } |
48 | |
49 | /** |
50 | Computes the total amount due. |
51 | @return the amount due |
52 | */ |
53 | public double getAmountDue() |
54 | { |
55 | double amountDue = 0; |
56 | for (int i = 0; i < items.size(); i++) |
57 | { |
58 | Item nextItem = (Item)items.get(i); |
59 | amountDue = amountDue + nextItem.getTotalPrice(); |
60 | } |
61 | return amountDue; |
62 | } |
63 | |
64 | private Address billingAddress; |
65 | private ArrayList items; |
66 | } |
1 | /** |
2 | Describes a quantity an article to purchase and its price. |
3 | */ |
4 | class Item |
5 | { |
6 | /** |
7 | Constructs an item from the product and quantity |
8 | @param aProduct the product |
9 | @param aQuantity the item quantity |
10 | */ |
11 | public Item(Product aProduct, int aQuantity) |
12 | { |
13 | theProduct = aProduct; |
14 | quantity = aQuantity; |
15 | } |
16 | |
17 | /** |
18 | Computes the total cost of this item. |
19 | @return the total price |
20 | */ |
21 | public double getTotalPrice() |
22 | { |
23 | return theProduct.getPrice() * quantity; |
24 | } |
25 | |
26 | /** |
27 | Formats this item. |
28 | @return a formatted string of this item |
29 | */ |
30 | public String format() |
31 | { |
32 | final int COLUMN_WIDTH = 30; |
33 | String description = theProduct.getDescription(); |
34 | |
35 | String r = description; |
36 | |
37 | // pad with spaces to fill column |
38 | |
39 | int pad = COLUMN_WIDTH - description.length(); |
40 | for (int i = 1; i <= pad; i++) |
41 | r = r + " "; |
42 | |
43 | r = r + theProduct.getPrice() |
44 | + " " + quantity |
45 | + " " + getTotalPrice(); |
46 | |
47 | return r; |
48 | } |
49 | |
50 | private int quantity; |
51 | private Product theProduct; |
52 | } |
1 | /** |
2 | Describes a product with a description and a price |
3 | */ |
4 | class Product |
5 | { |
6 | /** |
7 | Constructs a product from a description and a price. |
8 | @param aDescription the product description |
9 | @param aPrice the product price |
10 | */ |
11 | public Product(String aDescription, double aPrice) |
12 | { |
13 | description = aDescription; |
14 | price = aPrice; |
15 | } |
16 | |
17 | /** |
18 | Gets the product description. |
19 | @return the description |
20 | */ |
21 | public String getDescription() |
22 | { |
23 | return description; |
24 | } |
25 | |
26 | /** |
27 | Gets the product price. |
28 | @return the unit price |
29 | */ |
30 | public double getPrice() |
31 | { |
32 | return price; |
33 | } |
34 | |
35 | private String description; |
36 | private double price; |
37 | } |
38 |
1 | /** |
2 | Describes a mailing address. |
3 | */ |
4 | class Address |
5 | { |
6 | /** |
7 | Constructs a mailing address. |
8 | @param aName the recipient name |
9 | @param aStreet the street |
10 | @param aCity the city |
11 | @param aState the 2-letter state code |
12 | @param aZip the ZIP postal code |
13 | */ |
14 | public Address(String aName, String aStreet, |
15 | String aCity, String aState, String aZip) |
16 | { |
17 | name = aName; |
18 | street = aStreet; |
19 | city = aCity; |
20 | state = aState; |
21 | zip = aZip; |
22 | } |
23 | |
24 | /** |
25 | Formats the address. |
26 | @return the address as a string with 3 lines |
27 | */ |
28 | public String format() |
29 | { |
30 | return name + "\n" + street + "\n" |
31 | + city + ", " + state + " " + zip; |
32 | } |
33 | |
34 | private String name; |
35 | private String street; |
36 | private String city; |
37 | private String state; |
38 | private String zip; |
39 | } |
40 |
Enter Customer Number A = OK
Enter PIN A = OK
Select Account A = Checking B = Savings C = Exit
Balance = balance in selected account Enter amount and select transaction A = Withdraw B = Deposit C = Cancel
Keypad
|
get value entered
|
|
Customer
|
get accounts
|
|
match number and PIN | |
Bank
|
find customer
|
Customer |
read customers | |
ATM
|
set state
|
Customer |
select customer | Bank |
select account | BankAccount |
execute transaction | Keypad |
public class ATM { /** Gets PIN from keypad, finds customer in bank. If found sets state to ACCOUNT, else to START. */ public void selectCustomer() { } /** Sets current account to checking or savings. Sets state to TRANSACT @param account one of CHECKING_ACCOUNT or SAVINGS_ACCOUNT */ public void selectAccount(int account) { } /** Withdraws amount typed in keypad from current account. Sets state to ACCOUNT. */ Public void withdraw() { } /** Deposits amount typed in keypad to current account. Sets state to ACCOUNT. */ Public void deposit() { } /** Sets state and updates display message. @param state the next state */ public void setState(int newState) { } }
1 | import javax.swing.JFrame; |
2 | |
3 | /** |
4 | A simulation of an automatic teller machine |
5 | */ |
6 | public class ATMSimulation |
7 | { |
8 | public static void main(String[] args) |
9 | { |
10 | JFrame frame = new ATM(); |
11 | frame.setTitle("First National Bank of Java"); |
12 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
13 | frame.pack(); |
14 | frame.show(); |
15 | } |
16 | } |
17 |
1 | import java.awt.Container; |
2 | import java.awt.FlowLayout; |
3 | import java.awt.GridLayout; |
4 | import java.awt.event.ActionEvent; |
5 | import java.awt.event.ActionListener; |
6 | import java.io.IOException; |
7 | import javax.swing.JButton; |
8 | import javax.swing.JFrame; |
9 | import javax.swing.JOptionPane; |
10 | import javax.swing.JPanel; |
11 | import javax.swing.JTextArea; |
12 | |
13 | /** |
14 | A frame displaying the components of an ATM |
15 | */ |
16 | class ATM extends JFrame |
17 | { |
18 | /** |
19 | Constructs the user interface of the ATM application. |
20 | */ |
21 | public ATM() |
22 | { |
23 | // initialize bank and customers |
24 | |
25 | theBank = new Bank(); |
26 | try |
27 | { |
28 | theBank.readCustomers("customers.txt"); |
29 | } |
30 | catch(IOException e) |
31 | { |
32 | JOptionPane.showMessageDialog(null, |
33 | "Error opening accounts file."); |
34 | } |
35 | |
36 | // construct components |
37 | |
38 | pad = new Keypad(); |
39 | |
40 | display = new JTextArea(4, 20); |
41 | |
42 | aButton = new JButton(" A "); |
43 | aButton.addActionListener(new AButtonListener()); |
44 | |
45 | bButton = new JButton(" B "); |
46 | bButton.addActionListener(new BButtonListener()); |
47 | |
48 | cButton = new JButton(" C "); |
49 | cButton.addActionListener(new CButtonListener()); |
50 | |
51 | // add components to content pane |
52 | |
53 | JPanel buttonPanel = new JPanel(); |
54 | buttonPanel.setLayout(new GridLayout(3, 1)); |
55 | buttonPanel.add(aButton); |
56 | buttonPanel.add(bButton); |
57 | buttonPanel.add(cButton); |
58 | |
59 | Container contentPane = getContentPane(); |
60 | contentPane.setLayout(new FlowLayout()); |
61 | contentPane.add(pad); |
62 | contentPane.add(display); |
63 | contentPane.add(buttonPanel); |
64 | |
65 | setState(START_STATE); |
66 | } |
67 | |
68 | /** |
69 | Sets the current customer number to the keypad value |
70 | and sets state to PIN. |
71 | */ |
72 | public void setCustomerNumber() |
73 | { |
74 | customerNumber = (int)pad.getValue(); |
75 | setState(PIN_STATE); |
76 | } |
77 | |
78 | /** |
79 | Gets PIN from keypad, finds customer in bank. |
80 | If found sets state to ACCOUNT, else to START. |
81 | */ |
82 | public void selectCustomer() |
83 | { |
84 | int pin = (int)pad.getValue(); |
85 | currentCustomer |
86 | = theBank.findCustomer(customerNumber, pin); |
87 | if (currentCustomer == null) |
88 | setState(START_STATE); |
89 | else |
90 | setState(ACCOUNT_STATE); |
91 | } |
92 | |
93 | /** |
94 | Sets current account to checking or savings. Sets |
95 | state to TRANSACT |
96 | @param account one of CHECKING_ACCOUNT or SAVINGS_ACCOUNT |
97 | */ |
98 | public void selectAccount(int account) |
99 | { |
100 | if (account == CHECKING_ACCOUNT) |
101 | currentAccount = currentCustomer.getCheckingAccount(); |
102 | else |
103 | currentAccount = currentCustomer.getSavingsAccount(); |
104 | setState(TRANSACT_STATE); |
105 | } |
106 | |
107 | /** |
108 | Withdraws amount typed in keypad from current account. |
109 | Sets state to ACCOUNT. |
110 | */ |
111 | public void withdraw() |
112 | { |
113 | currentAccount.withdraw(pad.getValue()); |
114 | setState(ACCOUNT_STATE); |
115 | } |
116 | |
117 | /** |
118 | Deposits amount typed in keypad to current account. |
119 | Sets state to ACCOUNT. |
120 | */ |
121 | public void deposit() |
122 | { |
123 | currentAccount.deposit(pad.getValue()); |
124 | setState(ACCOUNT_STATE); |
125 | } |
126 | |
127 | /** |
128 | Sets state and updates display message. |
129 | @param state the next state |
130 | */ |
131 | public void setState(int newState) |
132 | { |
133 | state = newState; |
134 | pad.clear(); |
135 | if (state == START_STATE) |
136 | display.setText("Enter customer number\nA = OK"); |
137 | else if (state == PIN_STATE) |
138 | display.setText("Enter PIN\nA = OK"); |
139 | else if (state == ACCOUNT_STATE) |
140 | display.setText("Select Account\n" |
141 | + "A = Checking\nB = Savings\nC = Exit"); |
142 | else if (state == TRANSACT_STATE) |
143 | display.setText("Balance = " |
144 | + currentAccount.getBalance() |
145 | + "\nEnter amount and select transaction\n" |
146 | + "A = Withdraw\nB = Deposit\nC = Cancel"); |
147 | } |
148 | |
149 | private class AButtonListener implements ActionListener |
150 | { |
151 | public void actionPerformed(ActionEvent event) |
152 | { |
153 | if (state == START_STATE) |
154 | setCustomerNumber(); |
155 | else if (state == PIN_STATE) |
156 | selectCustomer(); |
157 | else if (state == ACCOUNT_STATE) |
158 | selectAccount(CHECKING_ACCOUNT); |
159 | else if (state == TRANSACT_STATE) |
160 | withdraw(); |
161 | } |
162 | } |
163 | |
164 | private class BButtonListener implements ActionListener |
165 | { |
166 | public void actionPerformed(ActionEvent event) |
167 | { |
168 | if (state == ACCOUNT_STATE) |
169 | selectAccount(SAVINGS_ACCOUNT); |
170 | else if (state == TRANSACT_STATE) |
171 | deposit(); |
172 | } |
173 | } |
174 | |
175 | private class CButtonListener implements ActionListener |
176 | { |
177 | public void actionPerformed(ActionEvent event) |
178 | { |
179 | if (state == ACCOUNT_STATE) |
180 | setState(START_STATE); |
181 | else if (state == TRANSACT_STATE) |
182 | setState(ACCOUNT_STATE); |
183 | } |
184 | } |
185 | |
186 | private int state; |
187 | private int customerNumber; |
188 | private Customer currentCustomer; |
189 | private BankAccount currentAccount; |
190 | private Bank theBank; |
191 | |
192 | private JButton aButton; |
193 | private JButton bButton; |
194 | private JButton cButton; |
195 | |
196 | private KeyPad pad; |
197 | private JTextArea display; |
198 | |
199 | private static final int START_STATE = 1; |
200 | private static final int PIN_STATE = 2; |
201 | private static final int ACCOUNT_STATE = 3; |
202 | private static final int TRANSACT_STATE = 4; |
203 | |
204 | private static final int CHECKING_ACCOUNT = 1; |
205 | private static final int SAVINGS_ACCOUNT = 2; |
206 | } |
1 | import java.awt.BorderLayout; |
2 | import java.awt.GridLayout; |
3 | import java.awt.event.ActionEvent; |
4 | import java.awt.event.ActionListener; |
5 | import javax.swing.JButton; |
6 | import javax.swing.JPanel; |
7 | import javax.swing.JTextField; |
8 | |
9 | /** |
10 | A component that lets the user enter a number, using |
11 | a button pad labeled with digits |
12 | */ |
13 | public class KeyPad extends JPanel |
14 | { |
15 | /** |
16 | Constructs the keypad panel. |
17 | */ |
18 | public KeyPad() |
19 | { |
20 | setLayout(new BorderLayout()); |
21 | |
22 | // add display field |
23 | |
24 | display = new JTextField(); |
25 | add(display, "North"); |
26 | |
27 | // make button panel |
28 | |
29 | buttonPanel = new JPanel(); |
30 | buttonPanel.setLayout(new GridLayout(4, 3)); |
31 | |
32 | // add digit buttons |
33 | |
34 | addButton("7"); |
35 | addButton("8"); |
36 | addButton("9"); |
37 | addButton("4"); |
38 | addButton("5"); |
39 | addButton("6"); |
40 | addButton("1"); |
41 | addButton("2"); |
42 | addButton("3"); |
43 | addButton("0"); |
44 | addButton("."); |
45 | |
46 | // add clear entry button |
47 | |
48 | clearButton = new JButton("CE"); |
49 | buttonPanel.add(clearButton); |
50 | |
51 | class ClearButtonListener implements ActionListener |
52 | { |
53 | public void actionPerformed(ActionEvent event) |
54 | { |
55 | display.setText(""); |
56 | } |
57 | } |
58 | ActionListener listener = new ClearButtonListener(); |
59 | |
60 | clearButton.addActionListener(new |
61 | ClearButtonListener()); |
62 | |
63 | add(buttonPanel, "Center"); |
64 | } |
65 | |
66 | /** |
67 | Adds a button to the button panel |
68 | @param label the button label |
69 | */ |
70 | private void addButton(final String label) |
71 | { |
72 | class DigitButtonListener implements ActionListener |
73 | { |
74 | public void actionPerformed(ActionEvent event) |
75 | { |
76 | |
77 | // don't add two decimal points |
78 | if (label.equals(".") |
79 | && display.getText().indexOf(".") != -1) |
80 | return; |
81 | |
82 | // append label text to button |
83 | display.setText(display.getText() + label); |
84 | } |
85 | } |
86 | |
87 | JButton button = new JButton(label); |
88 | buttonPanel.add(button); |
89 | ActionListener listener = new DigitButtonListener(); |
90 | button.addActionListener(listener); |
91 | } |
92 | |
93 | /** |
94 | Gets the value that the user entered. |
95 | @return the value in the text field of the keypad |
96 | */ |
97 | public double getValue() |
98 | { |
99 | return Double.parseDouble(display.getText()); |
100 | } |
101 | |
102 | /** |
103 | Clears the dislay. |
104 | */ |
105 | public void clear() |
106 | { |
107 | display.setText(""); |
108 | } |
109 | |
110 | private JPanel buttonPanel; |
111 | private JButton clearButton; |
112 | private JTextField display; |
113 | } |
114 |
1 | import java.io.BufferedReader; |
2 | import java.io.FileReader; |
3 | import java.io.IOException; |
4 | import java.util.ArrayList; |
5 | import java.util.StringTokenizer; |
6 | |
7 | /** |
8 | A bank contains customers with bank accounts. |
9 | */ |
10 | public class Bank |
11 | { |
12 | /** |
13 | Constructs a bank with no customers. |
14 | */ |
15 | public Bank() |
16 | { |
17 | customers = new ArrayList(); |
18 | } |
19 | |
20 | /** |
21 | Reads the customer numbers and pins |
22 | and initializes the bank accounts. |
23 | @param filename the name of the customer file |
24 | */ |
25 | public void readCustomers(String filename) |
26 | throws IOException |
27 | { |
28 | BufferedReader in = new BufferedReader |
29 | (new FileReader(filename)); |
30 | boolean done = false; |
31 | while (!done) |
32 | { |
33 | String inputLine = in.readLine(); |
34 | if (inputLine == null) done = true; |
35 | else |
36 | { |
37 | StringTokenizer tokenizer |
38 | = new StringTokenizer(inputLine); |
39 | int number |
40 | = Integer.parseInt(tokenizer.nextToken()); |
41 | int pin |
42 | = Integer.parseInt(tokenizer.nextToken()); |
43 | |
44 | Customer c = new Customer(number, pin); |
45 | addCustomer(c); |
46 | } |
47 | } |
48 | in.close(); |
49 | } |
50 | |
51 | /** |
52 | Adds a customer to the bank. |
53 | @param c the customer to add |
54 | */ |
55 | public void addCustomer(Customer c) |
56 | { |
57 | customers.add(c); |
58 | } |
59 | |
60 | /** |
61 | Finds a customer in the bank. |
62 | @param aNumber a customer number |
63 | @param aPin a personal identification number |
64 | @return the matching customer, or null if no customer |
65 | matches |
66 | */ |
67 | public Customer findCustomer(int aNumber, int aPin) |
68 | { |
69 | for (int i = 0; i < customers.size(); i++) |
70 | { |
71 | Customer c = (Customer)customers.get(i); |
72 | if (c.match(aNumber, aPin)) |
73 | return c; |
74 | } |
75 | return null; |
76 | } |
77 | |
78 | private ArrayList customers; |
79 | } |
80 | |
81 |
1 | /** |
2 | A bank customer with a checking and savings account. |
3 | */ |
4 | public class Customer |
5 | { |
6 | /** |
7 | Constructs a customer with a given number and PIN. |
8 | @param aNumber the customer number |
9 | @param PIN the personal identification number |
10 | */ |
11 | public Customer(int aNumber, int aPin) |
12 | { |
13 | customerNumber = aNumber; |
14 | pin = aPin; |
15 | checkingAccount = new BankAccount(); |
16 | savingsAccount = new BankAccount(); |
17 | } |
18 | |
19 | /** |
20 | Tests if this customer matches a customer number |
21 | and PIN. |
22 | @param aNumber a customer number |
23 | @param aPin a personal identification number |
24 | @return true if the customer number and PIN match |
25 | */ |
26 | public boolean match(int aNumber, int aPin) |
27 | { |
28 | return customerNumber == aNumber && pin == aPin; |
29 | } |
30 | |
31 | /** |
32 | Gets the checking account of this customer. |
33 | @return the checking account |
34 | */ |
35 | public BankAccount getCheckingAccount() |
36 | { |
37 | return checkingAccount; |
38 | } |
39 | |
40 | /** |
41 | Gets the savings account of this customer. |
42 | @return the checking account |
43 | */ |
44 | public BankAccount getSavingsAccount() |
45 | { |
46 | return savingsAccount; |
47 | } |
48 | |
49 | private int customerNumber; |
50 | private int pin; |
51 | private BankAccount checkingAccount; |
52 | private BankAccount savingsAccount; |
53 | } |