2. All transactions at an ATM
class AccountService {
List<Transaction> transactionsAt(int accountId, ATM atm) {
List<Transaction> transactionList = new List<Transaction>();
for (Transaction txn : transactions)
if (transaction.wasAtLocation(atm.getLocationId()))
transactionList.add(txn);
return transactionList;
}
}
class Transaction {
ATM atm;
boolean wasAtLocation(int locationId) {
return atm.getLocationId() == locationId;
}
}
3. All transactions at an ATMAll transactions at an ATM
class AccountService {
List<Transaction> transactionsAt(int accountId, ATM atm) {
List<Transaction> transactionList = new List<Transaction>();
for (Transaction txn : transactions)
if (transaction.wasAt(atm))if (transaction.wasAt(atm))
transactionList.add(txn);
return transactionList;
}
}
class Transaction {
ATM atm;
boolean wasAt(ATM atm) {boolean wasAt(ATM atm) {
return this.atm.equals(locationId);return this.atm.equals(locationId);
}
}
4. Pass object not its data
Encasulation can be broken across methods
5. class Customer {
static double eligibilityForHomeLoan = 500000;
static double eligibilityForPersonalLoan = 10000;
double salary;
boolean targetForHomeLoan() {
return salary > eligibilityForHomeLoan;
}
boolean targetForPersonalLoan() {
return salary > eligibilityForPersonalLoan;
}
}
Should target a customer for loan?
6. Should target a customer for loan?Should target a customer for loan?
class Customer {
Salary salary;Salary salary;
boolean targetForHomeLoan() {
return salary.isEligibleForHomeLoan();return salary.isEligibleForHomeLoan();
}
}
class Salary {class Salary {
double amount;double amount;
static double eligibilityForHomeLoan = 500000;static double eligibilityForHomeLoan = 500000;
Salary(double amount) {Salary(double amount) {
this.amount = amount;this.amount = amount;
}}
boolean isEligibleForLoan() {boolean isEligibleForLoan() {
return amount > eligibilityForHomeLoan.amount;return amount > eligibilityForHomeLoan.amount;
}}
}}
7. Avoid primitives in your domain
Primitives not only language but can be domain
primitives e.g. Money/Date/Currency
8. class Customer {
Set<Account> accounts;
Set<Account> getAccounts() {
return accounts;
}
}
class CustomerService {
void addAccount(Customer customer) {
Account account = new Account();
customer.getAccounts().add(account);
}
}
Open new account for a customer
9. class Customer {
Set<Account> accounts;
Account[] getAccounts() {Account[] getAccounts() {
return accounts.toArray();return accounts.toArray();
}}
void addNewAccount() {void addNewAccount() {
Account account = new Account();Account account = new Account();
accounts.add(account);accounts.add(account);
}}
}
class CustomerService {
void addAccount(Customer customer) {
customer.addNewAccount();customer.addNewAccount();
}
}
Open new account for a customerOpen new account for a customer
29. class Customer {
String name;
Date dateOfBirth;
public void validateForNew() throws ValidationException {
ValidationException exception = new ValidationException();
if (name == null || name.isEmpty())
exception.add(“Name not specified”);
if (dateOfBirth == null)
exception.add(“Date of birth not specified”);
else if (dateOfBirth.isBefore(1990))
exception.add(“below 20 years are not eligible”);
if (exception.hasErrors()) {
throw exception;
}
}
}
New Customer
30. class Customer {
String name;
Date dateOfBirth;
public ValidationError validateForNew() {public ValidationError validateForNew() {
ValidationError error = new ValidationError();ValidationError error = new ValidationError();
if (name == null || name.isEmpty())
error.add(“Name not specified”);
if (dateOfBirth == null)
error.add(“Date of birth not specified”);
else if (dateOfBirth.isBefore(1990))
error.add(“below 20 years are not eligible”);
return error;return error;
}
}
New CustomerNew Customer
32. public class Customer {
public void gotMarried() {
title = "Mrs";
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
if (!firstName.equals(customer.firstName)) return false;
if (!lastName.equals(customer.lastName)) return false;
if (!title.equals(customer.title)) return false;
return true;
}
public int hashCode() {
int result = firstName.hashCode();
result = 31 * result + lastName.hashCode();
result = 31 * result + title.hashCode();
return result;
}
}
Customer got married
33. public void test() {
Customer customer = new Customer("foo", "bar", "Miss");
Map map = new HashMap();
map.put(customer, "rich");
assertTrue(map.get(customer) != null);
customer.gotMarried();
assertTrue(map.get(customer) != null); <-- FailsassertTrue(map.get(customer) != null); <-- Fails
}
Customer got married
35. Account account = AccountRepository.load(1);
....
cleanUp(account);
public static void cleanUp(Account account) {
if (null != account) {
deleteAccount(account, null);
account = null;
}
}
Get rid of large object from memory
36. Objects references are always passed by value
Thats why C# has explicit pass by ref (not
recommending essentially)
37. Class Customer {
Name name;
Date dateOfBirth;
Accounts accounts;
Name getName() {
if (name == null) name = new Name();
return name;
}
}
Get customer's name
40. public class Customer {
List<Account> accounts = new ArrayList<Account>();
public void isAccountInactive(String accountNumber, int
maxInactivityAllowed) {
int i = accounts.indexOf(new Account(accountNumber));
Account account = accounts.get(i);
inactive(account, maxInactivityAllowed);
}
private static boolean inactive(Account account, int
maxInactivityAllowed) {
return account.getLastActivity().within(maxInactivityAllowed);
}
}
What can we do here?
41. public class Customer {
List<Account> accounts = new ArrayList<Account>();
public void isAccountInactive(String accountNumber, int
maxInactivityAllowed) {
int i = accounts.indexOf(new Account(accountNumber));
Account account = accounts.get(i);
account.inactive(maxInactivityAllowed);account.inactive(maxInactivityAllowed);
}
}
Look for staticsLook for statics
42. Look out for static methods and hints (by IDE) to
make methods static
Use the suggestion by not accepting it