SlideShare a Scribd company logo
1 of 49
Simple Programming/Design Tidbits
Banking application
Customer, Accounts, Transactions, ATM,
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;
}
}
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);
}
}
Pass object not its data
Encasulation can be broken across methods
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?
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;
}}
}}
Avoid primitives in your domain
Primitives not only language but can be domain
primitives e.g. Money/Date/Currency
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
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
Collections are mutable, donot expose them
class Customer {
Set<Account> accounts;
Money balance() {
Money total = Money.Zero();
for (Account account : accounts) {
total += account.getBalance();
}
return total;
}
Money inactiveAccounts() {
for (Account account : accounts) {
if (account.isInactive())
inactiveAccounts.add(account);
}
}
}
Customer's accounts
class Customer {
Accounts accounts;Accounts accounts;
}
class Accountsclass Accounts {
Set<Account> accounts;Set<Account> accounts;
Money total = Money.Zero();
Money balance() {
for (Account account : accounts) {
total += account.getBalance();
}
return total;
}
Money inactiveAccounts() {
for (Account account : accounts) {
if (account.isInactive())
inactiveAccounts.add(account);
}
}
}
Customer's accounts
Collections are primitives
Create domain specific collections
class Account {
InterestPlan interestPlan;
Money bal;
Money applyInterest() {
switch (interestPlan) {
case Simple: interest = new SICalc().calculate(bal);
case Compound: interest = new CICalc().calculate(bal);
......
}
bal += interest;
}
}
enum InterestPlan {
Simple, Compound, InflationAdjusted,
DurationDependent
}
Apply interest
class Account {
InterestPlan interestPlan;
Money bal;
static Map calculators = {static Map calculators = {
Simple => new SICalc(),Simple => new SICalc(),
Compound => new CICalc();Compound => new CICalc();
..........
}}
Money applyInterest() {
interest = calculators[interestPlan].calculate();interest = calculators[interestPlan].calculate();
}
}
Apply interestApply interest
Externalize if conditions
Can use for functions as value in map as well
class Account {
State state;
boolean transactionsAllowed() {
return state == State.Approved || state == State.Active;
}
boolean onlineTransactionAllowed() {
return state == State.Active || state == State.Locked;
}
}
enum State {
PendingApproval, Approved, Locked, Active, Closed
}
Account Security
class Account {
State state;
List transactionsAllowed = {State.Approved, State.Active};List transactionsAllowed = {State.Approved, State.Active};
List onlineTransactionsAllowed = {State.Locked, State.Active};List onlineTransactionsAllowed = {State.Locked, State.Active};
boolean transactionsAllowed() {
return transactionsAllowed.contains(state)transactionsAllowed.contains(state);
}
boolean onlineTransactionAllowed() {
return onlineTransactionsAllowed.contains(state)onlineTransactionsAllowed.contains(state);
}
}
enum State {
PendingApproval, Approved, Locked, Active, Closed
}
Account SecurityAccount Security
void monthlyReport() {
TransactionRepository repo = new TransactionRepository(...);
var list = repo.getBiggerTransactionsNotTransferredToSelf();
......
}
class TransactionRepository {
Transactions getBiggerTransactionsNotTransferredToSelf() {
Transactions transactions = loadTransactions(customerId);
....logic...
}
}
Suspicious Transactions
void monthlyReport() {
TransactionRepository repo = new TransactionRepository(...);
var list = repo.suspiciousTransactions()repo.suspiciousTransactions();
......
}
class TransactionRepository {
Transactions suspiciousTransactions()suspiciousTransactions() {
Transactions transactions = loadTransactions(customerId);
....logic...
}
}
Suspicious TransactionsSuspicious Transactions
Tell what not how
Keep implementation encapsulation
Seen more when doing TDD
class Customer {
String name;
Date dateOfBirth;
Accounts accounts;
Money salaryForLoanCalculations;
boolean targetForHomeLoan() {
return salaryForLoanCalculations.isEligibleForHomeLoan();
}
boolean targetForPersonalLoan() {
return salaryForLoanCalculations.isEligibileForPersLoan();
}
}
Customer
class Customer {
String name;
Date dateOfBirth;
Accounts accounts;
Money salary;Money salary;
boolean targetForHomeLoan() {
return salary.isEligibleForHomeLoan();return salary.isEligibleForHomeLoan();
}
boolean targetForPersonalLoan() {
return salary.isEligibileForPersonalLoan();return salary.isEligibileForPersonalLoan();
}
}
CustomerCustomer
Store what not what for
Seen more when doing TDD
class Customer {
String name;
Accounts accounts;
Money salary;
boolean isLoyal() {
if (salary > 20000 && accounts.balance() > 100000) {
return true;
}
return false;
}
}
Is Loyal Customer?
class Customer {
String name;
Accounts accounts;
Money salary;
boolean isLoyal() {
return salary > 20000 && accounts.balance() > 100000);return salary > 20000 && accounts.balance() > 100000);
}
}
Is Loyal Customer?Is Loyal Customer?
class Customer {
Accounts accounts;
boolean isLoyal() {
....
}
void issueCard(String accountNumber) {
Account account = accounts.get(accountNumber);
if (isLoyal() == true)
account.issuePlatinum();
else
account.issueOfLastType();
}
}
Issue platinum card?
class Customer {
Accounts accounts;
boolean isLoyal() {
....
}
void issueCard(String accountNumber) {
Account account = accounts.get(accountNumber);
if (isLoyal())if (isLoyal())
account.issuePlatinum();
else
account.issueOfLastType();
}
}
Issue platinum card?Issue platinum card?
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
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
Error during validation is not exceptional scenario
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
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
Don't use mutable fields for hashcode
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
Objects references are always passed by value
Thats why C# has explicit pass by ref (not
recommending essentially)
Class Customer {
Name name;
Date dateOfBirth;
Accounts accounts;
Name getName() {
if (name == null) name = new Name();
return name;
}
}
Get customer's name
Do not change data in getter, it deceives
ToString() is object's user interface
Reserve it and use for debugging only
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?
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
Look out for static methods and hints (by IDE) to
make methods static
Use the suggestion by not accepting it
class Account {
Transactions transactions;
Customer customer;
boolean suggestLinkingOfAccounts() {
if (transactions != null) {
Transactions customerXAs = transactions.with(customer);
return customerXAs.totalAmount() > 10000;
}
return false;
}
}
Suggest linking of accounts?
class Account {
Transactions transactions;
Customer customer;
boolean suggestLinkingOfAccounts() {
if (transactions != null) {
return transactions.withAndInExcessOf(customer, 10000);return transactions.withAndInExcessOf(customer, 10000);
}
return false;
}
}
Suggest linking of accounts?Suggest linking of accounts?
Tell don't ask at second level
(unless for performance reasons)
class Customer {
Transactions todaysTransactions;
Accounts accounts;
public Customer(Accounts account, Date date) {
this.accounts = accounts;
todaysTransactions = accounts.TransactionDoneOn(date);
}
Transactions todaysTransaction() {
Return todaysTransactions;
}
}
Today's transactions
class Customer {
Accounts accounts;
public Customer(Accounts account)public Customer(Accounts account) {
this.accounts = accounts;
}
Transactions allTransactionsOn(Date date) {Transactions allTransactionsOn(Date date) {
Return accounts.TransactionDoneOn(date);Return accounts.TransactionDoneOn(date);
}}
}
Today's transactions
Model state based on domain
State shouldn't be based on object's usage,
methods are for that
Suggestions might not always apply

More Related Content

Viewers also liked

Small is beautiful
Small is beautifulSmall is beautiful
Small is beautifulVivek Singh
 
Agile, architecture and architects
Agile, architecture and architectsAgile, architecture and architects
Agile, architecture and architectsVivek Singh
 
Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patternsVivek Singh
 
Effective use of time
Effective use of timeEffective use of time
Effective use of timeVivek Singh
 
Continuous integration at scale
Continuous integration at scaleContinuous integration at scale
Continuous integration at scaleVivek Singh
 
Product over project
Product over projectProduct over project
Product over projectVivek Singh
 
Bahmni Introduction
Bahmni IntroductionBahmni Introduction
Bahmni IntroductionVivek Singh
 
Bahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countriesBahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countriesVivek Singh
 
EIT-Digital_Annual-Report-2015-Digital-Version
EIT-Digital_Annual-Report-2015-Digital-VersionEIT-Digital_Annual-Report-2015-Digital-Version
EIT-Digital_Annual-Report-2015-Digital-VersionEdna Ayme-Yahil, PhD
 
Structured Approach to Solution Architecture
Structured Approach to Solution ArchitectureStructured Approach to Solution Architecture
Structured Approach to Solution ArchitectureAlan McSweeney
 

Viewers also liked (10)

Small is beautiful
Small is beautifulSmall is beautiful
Small is beautiful
 
Agile, architecture and architects
Agile, architecture and architectsAgile, architecture and architects
Agile, architecture and architects
 
Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patterns
 
Effective use of time
Effective use of timeEffective use of time
Effective use of time
 
Continuous integration at scale
Continuous integration at scaleContinuous integration at scale
Continuous integration at scale
 
Product over project
Product over projectProduct over project
Product over project
 
Bahmni Introduction
Bahmni IntroductionBahmni Introduction
Bahmni Introduction
 
Bahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countriesBahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countries
 
EIT-Digital_Annual-Report-2015-Digital-Version
EIT-Digital_Annual-Report-2015-Digital-VersionEIT-Digital_Annual-Report-2015-Digital-Version
EIT-Digital_Annual-Report-2015-Digital-Version
 
Structured Approach to Solution Architecture
Structured Approach to Solution ArchitectureStructured Approach to Solution Architecture
Structured Approach to Solution Architecture
 

Similar to Simple design/programming nuggets

Rajeev oops 2nd march
Rajeev oops 2nd marchRajeev oops 2nd march
Rajeev oops 2nd marchRajeev Sharan
 
#include iostream #include BankAccountClass.cpp #include .pdf
#include iostream #include BankAccountClass.cpp #include .pdf#include iostream #include BankAccountClass.cpp #include .pdf
#include iostream #include BankAccountClass.cpp #include .pdfANJANEYAINTERIOURGAL
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
help me Java projectI put problem and my own code in the linkmy .pdf
help me Java projectI put problem and my own code in the linkmy .pdfhelp me Java projectI put problem and my own code in the linkmy .pdf
help me Java projectI put problem and my own code in the linkmy .pdfarihantmum
 
Write a banking program that simulates the operation of your local ba.docx
 Write a banking program that simulates the operation of your local ba.docx Write a banking program that simulates the operation of your local ba.docx
Write a banking program that simulates the operation of your local ba.docxajoy21
 
No Hate on Java 8, But 9–14 Reign Supreme
No Hate on Java 8, But 9–14 Reign SupremeNo Hate on Java 8, But 9–14 Reign Supreme
No Hate on Java 8, But 9–14 Reign SupremeVMware Tanzu
 
Shangz R Brown Presentation
Shangz R Brown PresentationShangz R Brown Presentation
Shangz R Brown Presentationshangbaby
 
A Mock to far - GeeCon
A Mock to far -  GeeConA Mock to far -  GeeCon
A Mock to far - GeeConMichał Lipski
 
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdf
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdfC++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdf
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdfJUSTSTYLISH3B2MOHALI
 
The account problem in Java and Clojure
The account problem in Java and ClojureThe account problem in Java and Clojure
The account problem in Java and ClojureAlf Kristian Støyle
 
Barcelona Developers Conference 2011
Barcelona Developers Conference 2011Barcelona Developers Conference 2011
Barcelona Developers Conference 2011PayPal
 
Detroit ELEVATE Track 2
Detroit ELEVATE Track 2Detroit ELEVATE Track 2
Detroit ELEVATE Track 2Joshua Birk
 
The java class Account that simultes the Account class.pdf
   The java class Account that simultes  the Account class.pdf   The java class Account that simultes  the Account class.pdf
The java class Account that simultes the Account class.pdfakshay1213
 
Creating an Uber Clone - Part XXXII.pdf
Creating an Uber Clone - Part XXXII.pdfCreating an Uber Clone - Part XXXII.pdf
Creating an Uber Clone - Part XXXII.pdfShaiAlmog1
 
ELEVATE Advanced Workshop
ELEVATE Advanced WorkshopELEVATE Advanced Workshop
ELEVATE Advanced WorkshopJoshua Birk
 
Bank Program in JavaBelow is my code(havent finished, but it be .pdf
Bank Program in JavaBelow is my code(havent finished, but it be .pdfBank Program in JavaBelow is my code(havent finished, but it be .pdf
Bank Program in JavaBelow is my code(havent finished, but it be .pdfizabellejaeden956
 
Create a new Java project and add the Account class into the source co.pdf
Create a new Java project and add the Account class into the source co.pdfCreate a new Java project and add the Account class into the source co.pdf
Create a new Java project and add the Account class into the source co.pdfadmin618513
 

Similar to Simple design/programming nuggets (20)

Rajeev oops 2nd march
Rajeev oops 2nd marchRajeev oops 2nd march
Rajeev oops 2nd march
 
#include iostream #include BankAccountClass.cpp #include .pdf
#include iostream #include BankAccountClass.cpp #include .pdf#include iostream #include BankAccountClass.cpp #include .pdf
#include iostream #include BankAccountClass.cpp #include .pdf
 
project
projectproject
project
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
help me Java projectI put problem and my own code in the linkmy .pdf
help me Java projectI put problem and my own code in the linkmy .pdfhelp me Java projectI put problem and my own code in the linkmy .pdf
help me Java projectI put problem and my own code in the linkmy .pdf
 
Write a banking program that simulates the operation of your local ba.docx
 Write a banking program that simulates the operation of your local ba.docx Write a banking program that simulates the operation of your local ba.docx
Write a banking program that simulates the operation of your local ba.docx
 
No Hate on Java 8, But 9–14 Reign Supreme
No Hate on Java 8, But 9–14 Reign SupremeNo Hate on Java 8, But 9–14 Reign Supreme
No Hate on Java 8, But 9–14 Reign Supreme
 
Mock geecon2
Mock geecon2Mock geecon2
Mock geecon2
 
Shangz R Brown Presentation
Shangz R Brown PresentationShangz R Brown Presentation
Shangz R Brown Presentation
 
A Mock to far - GeeCon
A Mock to far -  GeeConA Mock to far -  GeeCon
A Mock to far - GeeCon
 
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdf
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdfC++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdf
C++ Bank Account Error Fix, full code. I am using Dev-C++ to Compile.pdf
 
The account problem in Java and Clojure
The account problem in Java and ClojureThe account problem in Java and Clojure
The account problem in Java and Clojure
 
Barcelona Developers Conference 2011
Barcelona Developers Conference 2011Barcelona Developers Conference 2011
Barcelona Developers Conference 2011
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
 
Detroit ELEVATE Track 2
Detroit ELEVATE Track 2Detroit ELEVATE Track 2
Detroit ELEVATE Track 2
 
The java class Account that simultes the Account class.pdf
   The java class Account that simultes  the Account class.pdf   The java class Account that simultes  the Account class.pdf
The java class Account that simultes the Account class.pdf
 
Creating an Uber Clone - Part XXXII.pdf
Creating an Uber Clone - Part XXXII.pdfCreating an Uber Clone - Part XXXII.pdf
Creating an Uber Clone - Part XXXII.pdf
 
ELEVATE Advanced Workshop
ELEVATE Advanced WorkshopELEVATE Advanced Workshop
ELEVATE Advanced Workshop
 
Bank Program in JavaBelow is my code(havent finished, but it be .pdf
Bank Program in JavaBelow is my code(havent finished, but it be .pdfBank Program in JavaBelow is my code(havent finished, but it be .pdf
Bank Program in JavaBelow is my code(havent finished, but it be .pdf
 
Create a new Java project and add the Account class into the source co.pdf
Create a new Java project and add the Account class into the source co.pdfCreate a new Java project and add the Account class into the source co.pdf
Create a new Java project and add the Account class into the source co.pdf
 

Recently uploaded

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Simple design/programming nuggets

  • 1. Simple Programming/Design Tidbits Banking application Customer, Accounts, Transactions, ATM,
  • 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
  • 10. Collections are mutable, donot expose them
  • 11. class Customer { Set<Account> accounts; Money balance() { Money total = Money.Zero(); for (Account account : accounts) { total += account.getBalance(); } return total; } Money inactiveAccounts() { for (Account account : accounts) { if (account.isInactive()) inactiveAccounts.add(account); } } } Customer's accounts
  • 12. class Customer { Accounts accounts;Accounts accounts; } class Accountsclass Accounts { Set<Account> accounts;Set<Account> accounts; Money total = Money.Zero(); Money balance() { for (Account account : accounts) { total += account.getBalance(); } return total; } Money inactiveAccounts() { for (Account account : accounts) { if (account.isInactive()) inactiveAccounts.add(account); } } } Customer's accounts
  • 13. Collections are primitives Create domain specific collections
  • 14. class Account { InterestPlan interestPlan; Money bal; Money applyInterest() { switch (interestPlan) { case Simple: interest = new SICalc().calculate(bal); case Compound: interest = new CICalc().calculate(bal); ...... } bal += interest; } } enum InterestPlan { Simple, Compound, InflationAdjusted, DurationDependent } Apply interest
  • 15. class Account { InterestPlan interestPlan; Money bal; static Map calculators = {static Map calculators = { Simple => new SICalc(),Simple => new SICalc(), Compound => new CICalc();Compound => new CICalc(); .......... }} Money applyInterest() { interest = calculators[interestPlan].calculate();interest = calculators[interestPlan].calculate(); } } Apply interestApply interest
  • 16. Externalize if conditions Can use for functions as value in map as well
  • 17. class Account { State state; boolean transactionsAllowed() { return state == State.Approved || state == State.Active; } boolean onlineTransactionAllowed() { return state == State.Active || state == State.Locked; } } enum State { PendingApproval, Approved, Locked, Active, Closed } Account Security
  • 18. class Account { State state; List transactionsAllowed = {State.Approved, State.Active};List transactionsAllowed = {State.Approved, State.Active}; List onlineTransactionsAllowed = {State.Locked, State.Active};List onlineTransactionsAllowed = {State.Locked, State.Active}; boolean transactionsAllowed() { return transactionsAllowed.contains(state)transactionsAllowed.contains(state); } boolean onlineTransactionAllowed() { return onlineTransactionsAllowed.contains(state)onlineTransactionsAllowed.contains(state); } } enum State { PendingApproval, Approved, Locked, Active, Closed } Account SecurityAccount Security
  • 19. void monthlyReport() { TransactionRepository repo = new TransactionRepository(...); var list = repo.getBiggerTransactionsNotTransferredToSelf(); ...... } class TransactionRepository { Transactions getBiggerTransactionsNotTransferredToSelf() { Transactions transactions = loadTransactions(customerId); ....logic... } } Suspicious Transactions
  • 20. void monthlyReport() { TransactionRepository repo = new TransactionRepository(...); var list = repo.suspiciousTransactions()repo.suspiciousTransactions(); ...... } class TransactionRepository { Transactions suspiciousTransactions()suspiciousTransactions() { Transactions transactions = loadTransactions(customerId); ....logic... } } Suspicious TransactionsSuspicious Transactions
  • 21. Tell what not how Keep implementation encapsulation Seen more when doing TDD
  • 22. class Customer { String name; Date dateOfBirth; Accounts accounts; Money salaryForLoanCalculations; boolean targetForHomeLoan() { return salaryForLoanCalculations.isEligibleForHomeLoan(); } boolean targetForPersonalLoan() { return salaryForLoanCalculations.isEligibileForPersLoan(); } } Customer
  • 23. class Customer { String name; Date dateOfBirth; Accounts accounts; Money salary;Money salary; boolean targetForHomeLoan() { return salary.isEligibleForHomeLoan();return salary.isEligibleForHomeLoan(); } boolean targetForPersonalLoan() { return salary.isEligibileForPersonalLoan();return salary.isEligibileForPersonalLoan(); } } CustomerCustomer
  • 24. Store what not what for Seen more when doing TDD
  • 25. class Customer { String name; Accounts accounts; Money salary; boolean isLoyal() { if (salary > 20000 && accounts.balance() > 100000) { return true; } return false; } } Is Loyal Customer?
  • 26. class Customer { String name; Accounts accounts; Money salary; boolean isLoyal() { return salary > 20000 && accounts.balance() > 100000);return salary > 20000 && accounts.balance() > 100000); } } Is Loyal Customer?Is Loyal Customer?
  • 27. class Customer { Accounts accounts; boolean isLoyal() { .... } void issueCard(String accountNumber) { Account account = accounts.get(accountNumber); if (isLoyal() == true) account.issuePlatinum(); else account.issueOfLastType(); } } Issue platinum card?
  • 28. class Customer { Accounts accounts; boolean isLoyal() { .... } void issueCard(String accountNumber) { Account account = accounts.get(accountNumber); if (isLoyal())if (isLoyal()) account.issuePlatinum(); else account.issueOfLastType(); } } Issue platinum card?Issue platinum card?
  • 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
  • 31. Error during validation is not exceptional scenario
  • 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
  • 34. Don't use mutable fields for hashcode
  • 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
  • 38. Do not change data in getter, it deceives
  • 39. ToString() is object's user interface Reserve it and use for debugging only
  • 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
  • 43. class Account { Transactions transactions; Customer customer; boolean suggestLinkingOfAccounts() { if (transactions != null) { Transactions customerXAs = transactions.with(customer); return customerXAs.totalAmount() > 10000; } return false; } } Suggest linking of accounts?
  • 44. class Account { Transactions transactions; Customer customer; boolean suggestLinkingOfAccounts() { if (transactions != null) { return transactions.withAndInExcessOf(customer, 10000);return transactions.withAndInExcessOf(customer, 10000); } return false; } } Suggest linking of accounts?Suggest linking of accounts?
  • 45. Tell don't ask at second level (unless for performance reasons)
  • 46. class Customer { Transactions todaysTransactions; Accounts accounts; public Customer(Accounts account, Date date) { this.accounts = accounts; todaysTransactions = accounts.TransactionDoneOn(date); } Transactions todaysTransaction() { Return todaysTransactions; } } Today's transactions
  • 47. class Customer { Accounts accounts; public Customer(Accounts account)public Customer(Accounts account) { this.accounts = accounts; } Transactions allTransactionsOn(Date date) {Transactions allTransactionsOn(Date date) { Return accounts.TransactionDoneOn(date);Return accounts.TransactionDoneOn(date); }} } Today's transactions
  • 48. Model state based on domain State shouldn't be based on object's usage, methods are for that
  • 49. Suggestions might not always apply