patternjavaMinor
Design for a Java Banking program
Viewed 0 times
designprogramjavabankingfor
Problem
UPDATE: Added concise problem summary and sample output log.
I tried coding a sample Java program to solve a problem statement:
Concise Problem summary:
Design and Implement an Engine that processes the SMS messages which
are sent from a users device (mobile). The messages will come to
engine as plain text data.
The message contains instructions to
Based on messages mentioned above, the messages can be of two types:
The operation corresponding to each type of message can have a pre and
post step and the actual operation step.
Important
Mobile Number Authentication PIN Transaction PIN Email Id
Populate this information in an in memory data structure / file system
which can be used for authentication. Authentication of PIN will
involve just validating the mobiie number against PIN numbers and
making sure they are same as expected values.
Sample output log
```
package com.banking.businessobject;
import java.math.BigInteger;
import java.util.Objects;
public c
I tried coding a sample Java program to solve a problem statement:
- Java Banking Demo Problem statement
- Complete code for Java Banking Demo
Concise Problem summary:
Design and Implement an Engine that processes the SMS messages which
are sent from a users device (mobile). The messages will come to
engine as plain text data.
The message contains instructions to
- Process a banking transaction
- Modify a users profile
Based on messages mentioned above, the messages can be of two types:
- Transaction request that makes changes to the account
- Request to modify user profile
The operation corresponding to each type of message can have a pre and
post step and the actual operation step.
Important
- Assume each user has a fixed. pre-defined and unique
Mobile Number Authentication PIN Transaction PIN Email Id
Populate this information in an in memory data structure / file system
which can be used for authentication. Authentication of PIN will
involve just validating the mobiie number against PIN numbers and
making sure they are same as expected values.
Sample output log
Enter the no of records:
1
Enter the record no:1
anurag|anurag@gmail.com|8105720566|7|2708|2708
Record written to the transaction file: anurag|anurag@gmail.com|8105720566|7|2708|2708
Enter the no of transactions:
1
Enter the transaction no:1
mo|7|7|200|2708|2708|anurag@eanurag.com
User found in the transaction file: anurag|anurag@gmail.com|8105720566|7|2708|2708
8105720566:PIN authenticated
User found in the transaction file: anurag|anurag@gmail.com|8105720566|7|2708|2708
Record written to the transaction file: anurag|anurag@eanurag.com|8105720566|7|2708|2708
8105720566:Update completed for mo|7|7|200|2708|2708|anurag@eanurag.comUser:```
package com.banking.businessobject;
import java.math.BigInteger;
import java.util.Objects;
public c
Solution
TransactionImpl#accountAuthentication
I'll start with
You can extract the big if in a separate method:
Then we can get rid of
Now for the
and inverted the negative conditions. If we need to check for a negative, we can use
We have many small methods now, but we can easily move them to their related class.
For example, we move
Transaction.java :
TransactionImpl.java :
Integers are automatically unboxed, there is no need to call
SmsGatewayImpl#receiveNextMessage
```
switch (trnObj.getTransactionType().toLowerCase()) {
case "tx":
authPinNotification = notifyPinAuthenticationResult(user, authenticated);
if (!authPinNotification.isEmpty() && authPinNotification != null) {
System.out.println(authPinNotification);
}
if (trnObj.getTransactionAmount() > 1000) {
transPinNotification = notifyTransPinAuthenticationResult(user, authenticated);
if (!transPinNotification.isEmpty() && transPinNotification != null) {
System.out.println(transPinNotification);
}
}
transactionNotification = notifyTransactionResult(user, trnObj, authenticated);
if (!transactionNotification.isEmpty() && transactionNotification != null) {
System.out.println(transactionNotification);
}
break;
case "mo":
authPinNotification = notifyPinAuthenticationResult(user, authenticated);
if (!authPinNotification.isEmpty() && authPinNotification != null) {
System.out.println(authPinNotification);
}
I'll start with
accountAuthentication method from TransactionImpl:@Override
public boolean accountAuthentication(User user, Transaction trnObj) {
boolean authentication = false;
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
if (userRecord.getMobileNumber().intValue() == user.getMobileNumber()
.intValue()
&& userRecord.getAccount().getAuthPin().intValue() == user
.getAccount().getAuthPin().intValue()) {
if (trnObj.getTransactionType().toLowerCase().equals("tx")
&& trnObj.getTransactionAmount().intValue() > 1000) {
if (userRecord.getAccount().getTransactionPin().intValue() != user
.getAccount().getTransactionPin().intValue()) {
return authentication;
}
}
authentication = true;
}
return authentication;
}You can extract the big if in a separate method:
@Override
public boolean accountAuthentication(User user, Transaction trnObj) {
boolean authentication = false;
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
if (isBadAuthentication(user, trnObj, userRecord)) {
return authentication;
}
authentication = true;
return authentication;
}Then we can get rid of
authentication temp variable:public boolean accountAuthentication2(User user, Transaction trnObj) {
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
return verifyAuthentication(user, trnObj, userRecord);
}Now for the
verifyAuthentication method, I extracted each condition in a separate method and inverted the negative conditions. If we need to check for a negative, we can use
!. private boolean verifyAuthentication(User user, Transaction trnObj, User userRecord) {
return verifyMobilePhone(user, userRecord) &&
verifyAuthPin(user, userRecord) &&
!isTxTransaction(trnObj) &&
!hasBigAmount(trnObj) &&
verifyTransactionPin(user, userRecord);
}
private boolean verifyTransactionPin(User user, User userRecord) {
return userRecord.getAccount().getTransactionPin().intValue() ==
user.getAccount().getTransactionPin().intValue();
}
private boolean hasBigAmount(Transaction trnObj) {
return trnObj.getTransactionAmount().intValue() > 1000;
}
private boolean isTxTransaction(Transaction trnObj) {
return trnObj.getTransactionType().toLowerCase().equals("tx");
}
private boolean verifyAuthPin(User user, User userRecord) {
return userRecord.getAccount().getAuthPin().intValue() ==
user.getAccount().getAuthPin().intValue();
}
private boolean verifyMobilePhone(User user, User userRecord) {
return userRecord.getMobileNumber().intValue() ==
user.getMobileNumber().intValue();
}We have many small methods now, but we can easily move them to their related class.
For example, we move
isTxTransaction and hasBigAmount right in the Transaction class:Transaction.java :
public boolean isTx() {
return getTransactionType().toLowerCase().equals("tx");
}
public boolean hasBigAmount() {
return getTransactionAmount().intValue() > 1000;
}TransactionImpl.java :
private boolean verifyAuthentication(User user, Transaction trnObj, User userRecord) {
return verifyMobilePhone(user, userRecord) &&
verifyAuthPin(user, userRecord) &&
!trnObj.isTx() &&
!trnObj.hasBigAmount() &&
verifyTransactionPin(user, userRecord);
}Integers are automatically unboxed, there is no need to call
intValue in hasBigAmount:public boolean hasBigAmount() {
return getTransactionAmount() > 1000;
}SmsGatewayImpl#receiveNextMessage
receiveNextMessage has this big switch:```
switch (trnObj.getTransactionType().toLowerCase()) {
case "tx":
authPinNotification = notifyPinAuthenticationResult(user, authenticated);
if (!authPinNotification.isEmpty() && authPinNotification != null) {
System.out.println(authPinNotification);
}
if (trnObj.getTransactionAmount() > 1000) {
transPinNotification = notifyTransPinAuthenticationResult(user, authenticated);
if (!transPinNotification.isEmpty() && transPinNotification != null) {
System.out.println(transPinNotification);
}
}
transactionNotification = notifyTransactionResult(user, trnObj, authenticated);
if (!transactionNotification.isEmpty() && transactionNotification != null) {
System.out.println(transactionNotification);
}
break;
case "mo":
authPinNotification = notifyPinAuthenticationResult(user, authenticated);
if (!authPinNotification.isEmpty() && authPinNotification != null) {
System.out.println(authPinNotification);
}
Code Snippets
@Override
public boolean accountAuthentication(User user, Transaction trnObj) {
boolean authentication = false;
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
if (userRecord.getMobileNumber().intValue() == user.getMobileNumber()
.intValue()
&& userRecord.getAccount().getAuthPin().intValue() == user
.getAccount().getAuthPin().intValue()) {
if (trnObj.getTransactionType().toLowerCase().equals("tx")
&& trnObj.getTransactionAmount().intValue() > 1000) {
if (userRecord.getAccount().getTransactionPin().intValue() != user
.getAccount().getTransactionPin().intValue()) {
return authentication;
}
}
authentication = true;
}
return authentication;
}@Override
public boolean accountAuthentication(User user, Transaction trnObj) {
boolean authentication = false;
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
if (isBadAuthentication(user, trnObj, userRecord)) {
return authentication;
}
authentication = true;
return authentication;
}public boolean accountAuthentication2(User user, Transaction trnObj) {
IFileIO fi = new FileIO();
User userRecord = fi.readTransactionFile(user);
return verifyAuthentication(user, trnObj, userRecord);
}private boolean verifyAuthentication(User user, Transaction trnObj, User userRecord) {
return verifyMobilePhone(user, userRecord) &&
verifyAuthPin(user, userRecord) &&
!isTxTransaction(trnObj) &&
!hasBigAmount(trnObj) &&
verifyTransactionPin(user, userRecord);
}
private boolean verifyTransactionPin(User user, User userRecord) {
return userRecord.getAccount().getTransactionPin().intValue() ==
user.getAccount().getTransactionPin().intValue();
}
private boolean hasBigAmount(Transaction trnObj) {
return trnObj.getTransactionAmount().intValue() > 1000;
}
private boolean isTxTransaction(Transaction trnObj) {
return trnObj.getTransactionType().toLowerCase().equals("tx");
}
private boolean verifyAuthPin(User user, User userRecord) {
return userRecord.getAccount().getAuthPin().intValue() ==
user.getAccount().getAuthPin().intValue();
}
private boolean verifyMobilePhone(User user, User userRecord) {
return userRecord.getMobileNumber().intValue() ==
user.getMobileNumber().intValue();
}public boolean isTx() {
return getTransactionType().toLowerCase().equals("tx");
}
public boolean hasBigAmount() {
return getTransactionAmount().intValue() > 1000;
}Context
StackExchange Code Review Q#114493, answer score: 4
Revisions (0)
No revisions yet.