Detta �r den programkod vi skrev -- anteckningarna �r gjorda bara f�r att vara ett st�d f�r minnet f�r dem som var d�r, och d�rf�r inte n�dv�ndigtvis fullst�ndiga eller ens sammanh�ngande. Betydligt mer hj�lp finns att h�mta i kompendiet.
OH-bilder finns h�r.
Vi b�rjade med att titta lite p� den konto-klass som vi skrev f�rra g�ngen, denna g�ng l�t vi n�gra av metoderna returnera v�rden:
class Account { private double balance = 10; // attribut private int accountNumber; public Account (int accountNumber) { // konstruktor // k�rs n�r kontot skapas balance = 0; this.accountNumber = accountNumber; } public int getAccountNumber() { return accountNumber; } public double deposit(double amount) { // metod if (amount >= 0) { balance += amount; return amount; } return 0; } public double withdraw(double amount) { if (amount < 0) { return 0; } if (amount > balance) { amount = balance; } balance -= amount; return amount; } public double getBalance() { return balance; } }
Jag f�rs�kte f�rklara vad som egentligen h�nder n�r vi skapar ett konto, och ritade (ungef�r) f�ljande figur:
D�refter b�rjade vi skissa p� en Bank-klass, och kom f�rst fram till att vi ville anv�nda en lista med konton i den:
class Bank { private List<Account> accounts = new ArrayList<Account>(); public Bank () { // egentligen on�dig } }
Vi ritade en figur som visar en bank med n�gra konton (det �r ungef�r denna slags figur ni skall rita i inl�mningsuppgift 3):
Jag visade sedan en klass som testar Account-klassen och en
Bank-klass -- test-klassen finns l�ngst ner p� denna sida. Vi skrev
sedan klassen Bank
s� h�r (i olika steg):
class Bank { private Listaccounts = new ArrayList (); private double noAmount = Double.NEGATIVE_INFINITY; public boolean createAccount(int accNo) { if (this.hasAccount(accNo)) { return false; } accounts.add(new Account(accNo)); return true; } public boolean hasAccount(int accNo) { if (getAccount(accNo) != null) { return true; } return false; } public double deposit(int accNo, double amount) { if (!hasAccount(accNo)) { return 0; } Account acc = getAccount(accNo); return acc.deposit(amount); } private Account getAccount(int accNo) { for (Account acc : accounts) { if (acc.getAccountNumber() == accNo) { return acc; } } return null; } public double getBalance(int accNo) { if (!hasAccount(accNo)) { return noAmount; } return getAccount(accNo).getBalance(); } public double withdraw(int accNo, double amount) { Account acc = getAccount(accNo); if (acc == null) { return noAmount; } return acc.withdraw(amount); } }
Vi kan testa v�rt program genom att k�ra bank-programmet ovan, mata in v�rden och se att vi f�r r�tt resultat. Men en b�ttre l�sning �r att anv�nda test-programmet:
class BankTesting { public static void main(String[] args) { new BankTesting().run(); } void run() { try { header("Testar klassen Account"); testAccount(); header("Testar klassen Bank"); testBank(); } catch (Exception e) { System.out.println("Testerna avbr�ts...: " + e.toString()); } } void header(String text) { System.out.println(); System.out.println("==== " + text + " ===="); System.out.println(); } void test(boolean condition, String message) { System.out.println((condition ? " OK" : "FEL") + ": " + message); if (!condition) { throw new RuntimeException(); } } boolean equals(double x, double y) { return Math.abs(x - y) < 0.001; } void testAccount() { Account acc1 = new Account(1010); Account acc2 = new Account(1020); test(acc1.getAccountNumber() == 1010, "Kontonummer"); test(acc2.getAccountNumber() == 1020, "Kontonummer"); test(equals(acc1.getBalance(), 0), "Startsaldo"); test(equals(acc2.getBalance(), 0), "Startsaldo"); test(equals(acc1.deposit(-100), 0), "Felaktig ins�ttning"); test(equals(acc1.getBalance(), 0), "Saldo efter otill�ten ins�ttning"); test(equals(acc1.deposit(100), 100), "Ins�ttning p� tomt konto"); test(equals(acc1.getBalance(), 100), "Ins�ttning och saldo p� tomt konto"); test(equals(acc1.deposit(50), 50), "Vanlig ins�ttning"); test(equals(acc1.getBalance(), 150), "Vanlig ins�ttning och saldo"); test(equals(acc2.getBalance(), 0), "Saldo p� tomt konto efter ins�ttning p� annat konto"); test(equals(acc1.withdraw(100), 100), "Vanligt uttag"); test(equals(acc1.getBalance(), 50), "Vanligt uttag och saldo"); test(equals(acc1.withdraw(200), 50), "�vertrassering"); test(equals(acc1.getBalance(), 0), "Saldo efter �vertrassering"); test(equals(acc1.deposit(50), 50), "Vanlig ins�ttning efter �vertrassering"); test(equals(acc1.getBalance(), 50), "Saldo efter �vertrassering"); } void testBank() { Bank bank1 = new Bank(); Bank bank2 = new Bank(); test(!bank1.hasAccount(1010), "Hittar inte konto som inte finns"); test(bank1.createAccount(1010), "Kan skapa konto med nytt kontonummer"); test(bank1.createAccount(1020), "Kan skapa konto med nytt kontonummer"); test(!bank1.createAccount(1010), "Kan inte skapa konto med gammalt kontonummer"); test(!bank1.createAccount(1020), "Kan inte skapa konto med gammalt kontonummer"); test(!bank2.hasAccount(1010), "Hittar inte konto som inte finns (ny bank)"); test(bank2.createAccount(1010), "Kan skapa konto med nytt kontonummer (ny bank)"); test(bank2.createAccount(1020), "Kan skapa konto med nytt kontonummer (ny bank)"); test(!bank2.createAccount(1010), "Kan inte skapa konto med gammalt kontonummer (ny bank)"); test(!bank2.createAccount(1020), "Kan inte skapa konto med gammalt kontonummer (ny bank)"); test(equals(bank1.deposit(1010, -100), 0), "Felaktig ins�ttning p� tomt konto"); test(equals(bank1.getBalance(1010), 0), "Saldo efter felaktig ins�ttning p� tomt konto"); test(equals(bank1.deposit(1010, 100), 100), "Korrekt ins�ttning p� tomt konto"); test(equals(bank1.getBalance(1010), 100), "Saldo efter ins�ttning p� tomt konto"); test(equals(bank1.deposit(1010, 350), 350), "Korrekt ins�ttning p� konto med pengar"); test(equals(bank1.getBalance(1010), 450), "Saldo efter ins�ttning p� konto med pengar"); test(equals(bank1.deposit(1010, -100), 0), "Felaktig ins�ttning p� konto med pengar"); test(equals(bank1.getBalance(1010), 450), "Saldo efter felaktig ins�ttning p� konto med pengar"); test(equals(bank1.withdraw(1010, 350), 350), "Korrekt uttag p� konto med pengar"); test(equals(bank1.getBalance(1010), 100), "Saldo efter uttag p� konto med pengar"); test(bank1.withdraw(1050, 100) < 0, "Inget uttag fr�n konto som inte finns"); } }
N�r vi nu k�rde programmet gick samtliga tester igenom. Detta s�tt att programmera -- dvs att f�rst skriva ett test-program och sedan skriva det egentliga programmet -- kallas ibland test driven design. N�r vi skriver test-programmet uppt�cker vi hur vi vill kunna anropa de ing�ende klasserna, och det hj�lper oss att designa dem b�ttre. Dessutom f�r vi ett s�tt att automatiskt kontrollera att v�rt program hela tiden fungerar (�ven om vi skulle g�ra �ndringar i det).
Om det �r n�got du undrar �ver s� �r du hj�rtligt v�lkommen till tisdagens extragenomg�ng (se schemat p� kurshemsidan).