SlideShare a Scribd company logo
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 beautiful
Vivek Singh
 
Agile, architecture and architects
Agile, architecture and architectsAgile, architecture and architects
Agile, architecture and architects
Vivek Singh
 
Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patterns
Vivek Singh
 
Effective use of time
Effective use of timeEffective use of time
Effective use of time
Vivek Singh
 
Continuous integration at scale
Continuous integration at scaleContinuous integration at scale
Continuous integration at scale
Vivek Singh
 
Product over project
Product over projectProduct over project
Product over project
Vivek Singh
 
Bahmni Introduction
Bahmni IntroductionBahmni Introduction
Bahmni Introduction
Vivek Singh
 
Bahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countriesBahmni, Scaling in multiple countries
Bahmni, Scaling in multiple countries
Vivek 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-Version
Edna Ayme-Yahil, PhD
 
Structured Approach to Solution Architecture
Structured Approach to Solution ArchitectureStructured Approach to Solution Architecture
Structured Approach to Solution Architecture
Alan 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 march
Rajeev 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 .pdf
ANJANEYAINTERIOURGAL
 
project
projectproject
project
Kabita Gurung
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
Thibaud 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 .pdf
arihantmum
 
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
ajoy21
 
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
VMware Tanzu
 
Mock geecon2
Mock geecon2Mock geecon2
Mock geecon2
Michał Lipski
 
Shangz R Brown Presentation
Shangz R Brown PresentationShangz R Brown Presentation
Shangz R Brown Presentation
shangbaby
 
A Mock to far - GeeCon
A Mock to far -  GeeConA Mock to far -  GeeCon
A Mock to far - GeeCon
Michał 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.pdf
JUSTSTYLISH3B2MOHALI
 
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
Alf Kristian Støyle
 
Barcelona Developers Conference 2011
Barcelona Developers Conference 2011Barcelona Developers Conference 2011
Barcelona Developers Conference 2011
PayPal
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
Salesforce Developers
 
Detroit ELEVATE Track 2
Detroit ELEVATE Track 2Detroit ELEVATE Track 2
Detroit ELEVATE Track 2
Joshua 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.pdf
akshay1213
 
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
ShaiAlmog1
 
ELEVATE Advanced Workshop
ELEVATE Advanced WorkshopELEVATE Advanced Workshop
ELEVATE Advanced Workshop
Joshua 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 .pdf
izabellejaeden956
 
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
admin618513
 

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

UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 

Recently uploaded (20)

UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 

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