----

Visitor Design Pattern Example

Visitor Design Pattern: The visitor design pattern is a way of separating some logic from an object structure on which it operates. Basically it allows you to add new operations on existing classes without modifying them, So visitor design pattern is a great way to provide a flexible design.


Note:  Visitor pattern has some flaws.
If we add a new class, the visitor class needs a new method. Furthermore, it is indeed likely that a new visiting method will need the definition of a new visitor, as well as a new accept method in every class of the hierarchy, visitor uses dual dispatching.

When to use: when you have a complex structure, i.e, a hierarchy, tree structure or something else that's not simply linear, you can apply the visitor to simplify the complex structure.

Lets understand it by one hierarchy problem example 


Here we have a base class Account and other three classes SavingAccount, CurrentAccount and LoanAccount classes which are derived from Account base class.
We can implement these classes as below with some more basic function.

Account.java
// an abstract class and can not be instantiated 

public abstract class Account {
protected int balance = 0;
        // an abstract method which will be overridden by child classes
public abstract String getAccountType();


public int getBalance() {

return balance;
}
}

SavingAccount.java


public class SavingAccount extends Account {

public SavingAccount() {

balance = 1000;// basic amount to open an account
}

@Override

public String getAccountType() {
return "Saving";
}
}

CurrentAccount.java


public class CurrentAccount extends Account {

private final int maxWithdrawalAmount = 10000;


public CurrentAccount() {

balance = 500;//some basic amount to open an account
}

@Override

public String getAccountType() {
return "Current";
}

public int getWithdrawalLimit() {

return maxWithdrawalAmount;
}
}

LoanAccount.java


public class LoanAccount extends Account {
private int paidAmount = 0;
private int loanAmount = 0;

public LoanAccount() {
loanAmount = 100000;// basic amount for a loan account
}

@Override
public String getAccountType() {
return "Loan";
}

public int getLoanAmount() {
return loanAmount;
}

@Override
public int getBalance() {
return balance = loanAmount - paidAmount;
}
}

Now suppose we want to display each account details, So we will write a new class say DisplayHandler.java and some logic to display each account details as following.

DisplayHandler.java
This class is responsible for displaying various informations for a given account.

public class DisplayHandler {
        // display the account details based on a given account type
public void displayDetails(Account account) {
if (account instanceof CurrentAccount) {
CurrentAccount currentAccount = (CurrentAccount) account;
System.out.println("Account type: " + account.getAccountType());
System.out.println("Account Balance: " + account.getBalance());
System.out.println("Withdrawal Limit: " + currentAccount.getWithdrawalLimit());
} else if (account instanceof SavingAccount) {
SavingAccount savingAccount = (SavingAccount) account;
System.out.println("Account type: " + account.getAccountType());
System.out.println("Account Balance: " + account.getBalance());
//savingAccount.someMethodCall();
} else if (account instanceof LoanAccount) {
LoanAccount loanAccount = (LoanAccount) account;
System.out.println("Account type: " + account.getAccountType());
System.out.println("Account Balance: " + account.getBalance());
System.out.println("Loan Amount: " + loanAccount.getLoanAmount());
}
                //here may be some more if else conditions for some other account type
}
}


Here in displayDetails method we can see many if else conditions and if we have more classes...


No comments :

Post a Comment