Aug 272011
 
What is Proxy Pattern?

Proxy is one of famous structural design pattern to “provide a surrogate or placeholder for another object to control access to it” (G.o.F).

image thumb96 Proxy Pattern tutorial and RMI example

In this diagram, you can see that Client want to doSomething() by the RealSubject. But we don’t want Client to interact with ReadSubject directly. Maybe there’s security reason or RealSubject is very costly, we can not deliver it to each Client. Instead we provide a proxy to each client, and when the client request to doSomething(), the RealSubject will do then.

When to use Proxy Pattern?

You use Proxy Pattern when you want to provide a representative of another object, for reasons such as access, speed, or security.

Proxy Pattern Example

bank atm proxy thumb Proxy Pattern tutorial and RMI example

Let take ATM and Bank as our example. The bank has so many customers and the cost for accessing to the Bank is so high (cost for traveling to the bank, cost for paying receptionist…). So that they provide ATMs, and via the ATM, customer can use the IBank to interact with the bank. Forgive me if I’m not good at describing but I will explain this better in Java language wlEmoticon smile33 Proxy Pattern tutorial and RMI example

First I will create an iBank interface which define some basic interactions between customers and bank.

package net.searchdaily.java.design.pattern.proxy;

/**
 * Proxy Pattern tutorial by http://java.searchdaily.net
 * 
 * @author namnvhue
 * 
 */
public interface IBank {
	/**
	 * Check account and return current balance
	 * 
	 * @param accountId
	 * @return
	 */
	public double checkBalance(String accountId);

	/**
	 * Withdraw amt $ from bank and return new balance if success, if not return
	 * current balance.
	 * 
	 * @param accountId
	 * @param amt
	 * @return
	 */
	public double withDraw(String accountId, double amt);

	/**
	 * Deposite $amt into account, if success return new balance, if not return
	 * current balance.
	 * 
	 * @param accountId
	 * @param amt
	 * @return
	 */
	public double deposit(String accountId, double amt);
}

Then I will create a Central Computer for the Bank, this computer will hold all of account and do all transactions (supposed so)

package net.searchdaily.java.design.pattern.proxy;

import java.util.HashMap;
import java.util.Map;

/**
 * Proxy Pattern tutorial by http://java.searchdaily.net
 * 
 * @author namnvhue
 * 
 */
public class BankCentralComputer implements IBank {
	Map accounts = new HashMap();

	public BankCentralComputer() {
		accounts.put("12345", 20000.0);
		accounts.put("11223", 30000.0);
		accounts.put("33112", 60000.0);
	}

	@Override
	public double checkBalance(String accountId) {
		if (validateAccount(accountId)) {
			return this.accounts.get(accountId);
		} else {
			System.out.println("Invalid Account");
			return 0.0;
		}
	}

	@Override
	public double withDraw(String accountId, double amt) {
		if (validateAccount(accountId)) {
			double currentBalance = this.accounts.get(accountId);
			double newBalance = currentBalance - amt;
			if (newBalance >= 0.0) {
				// Save account data
				this.accounts.put(accountId, newBalance);
				return newBalance;
			} else {
				System.out.println("You don't have enough money");
				return currentBalance;
			}
		} else {
			System.out.println("Invalid Account");
			return 0.0;
		}
	}

	@Override
	public double deposit(String accountId, double amt) {
		if (validateAccount(accountId)) {
			double currentBalance = this.accounts.get(accountId);
			double newBalance = currentBalance + amt;
			this.accounts.put(accountId, newBalance);
			return newBalance;
		} else {
			System.out.println("Invalid Account");
			return 0.0;
		}
	}

	boolean validateAccount(String accountId) {
		return this.accounts.containsKey(accountId);
	}

}

Now as it’s costly to use the Bank, they provide ATM everywhere for their customers

package net.searchdaily.java.design.pattern.proxy;

/**
 * Proxy Pattern tutorial by http://java.searchdaily.net
 * 
 * @author namnvhue
 * 
 */
public class ATM implements IBank {
	private IBank proxifiedBank;

	public ATM(IBank realBank) {
		if (realBank != null) {
			this.proxifiedBank = realBank;
		} else {
			this.proxifiedBank = new BankCentralComputer();
		}
	}

	@Override
	public double checkBalance(String accountId) {
		return this.proxifiedBank.checkBalance(accountId);
	}

	@Override
	public double withDraw(String accountId, double amt) {
		return this.proxifiedBank.withDraw(accountId, amt);
	}

	@Override
	public double deposit(String accountId, double amt) {
		return this.proxifiedBank.deposit(accountId, amt);
	}

}

As you can see, the ATM can do exactly what the Central Computer of the Bank do. Actually, the ATM  cannot do stuff like withDraw, deposit or checkBalance, but they have to ask another subject to do it. In this case if we construct the ATM without any specific real subject for it, it will use the Central Computer.

Now let’s see how some engineer will test the ATM at his weekend wlEmoticon smilewithtongueout7 Proxy Pattern tutorial and RMI example

Continue reading »