Java Submission to interfaces!!!

A common currency operation and exchange taken from a book : a demonstration in dummy code
(50$ + 100INR -30 EURO) convert to EURO

Solution :

Convert currency operation and exchange to one interface



public interface Expression {
	
	Expression add(Expression expression);
	Expression substract(Expression expression);
	Expression multiply (double multiplier );
	Expression divide(double divider);
	Expression reduceTo(Bank bank,MoneyUnit moneyUnit);

}
//representation of money in expression 
public class Money  implements Expression {
	
	
	private double amount ;
	private MoneyUnit unit;
	
	public Money(double amount,MoneyUnit unit) {
		this.amount = amount;
		this.unit = unit;
	}
	
	

	@Override
	public Expression add(Expression expression) {
		
		if(expression instanceof Money) {
			Money anotherMoney = (Money) expression;
			if(this.unit.equals(anotherMoney.unit)) {
				return new Money(this.amount+anotherMoney.amount, unit);
			}
		}
		
		return new Sum(this,expression);
	}

	@Override
	public Expression substract(Expression expression) {
		
		if(expression instanceof Money) {
			Money anotherMoney = (Money) expression;
			
			if(this.unit.equals(anotherMoney.unit)) {
				return new Money(this.amount-anotherMoney.amount, unit);
			}
		}
		return new Substract(this, expression);
	}

	@Override
	public Expression multiply(double multiplier) {
		return new Money(this.amount*multiplier,unit);
	}

	@Override
	public Expression divide(double divider) {
		return new Money(this.amount/divider, unit);
	}

	@Override
	public Expression reduceTo(Bank bank,MoneyUnit unit) {
		 Double exchangeRate = bank.getExchangeRate(this.unit, unit);
		 if (exchangeRate==null) {
			 //could be handled better 
			 throw new RuntimeException(String.format(
					 String.format("conversion rate is not registered between %s %s", 
							 this.unit,unit)));
		 }
		 
		 return new Money(this.amount*exchangeRate, unit);
	}

	@Override
	public String toString() {
		return  amount + unit.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(amount);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		result = prime * result + ((unit == null) ? 0 : unit.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Money other = (Money) obj;
		if (Double.doubleToLongBits(amount) != Double
				.doubleToLongBits(other.amount))
			return false;
		if (unit != other.unit)
			return false;
		return true;
	}

}


public enum MoneyUnit {
	
	DOLLAR("D"),
	INR("INR"),
	EURO("E");
	
	String symbol;
	private MoneyUnit(String _symbol) {
		this.symbol = _symbol;
		
	}
	@Override
	public String toString() {
		return symbol;
	}
	
}

//representation of Operation in expression 
public class Sum implements Expression {
    
	private Expression augment1;
	private Expression augment2;
	
	public Sum(Expression augment1,Expression augment2) {
		this.augment1 = augment1;
		this.augment2 = augment2;
	}
	@Override
	public Expression add(Expression expression) {
		
		 return new Sum(this, expression);
	
	}

	@Override
	public Expression substract(Expression expression) {
		return new Sum(this, expression.multiply(-1));
	}

	@Override
	public Expression multiply(double multiplier) {
		
		return new Sum(augment1.multiply(multiplier), augment2.multiply(multiplier));
	}

	@Override
	public Expression divide(double divider) {
		return new Sum(augment1.divide(divider), augment2.divide(divider));
	}

	@Override
	public Expression reduceTo(Bank bank,MoneyUnit moneyUnit) {
		
		return augment1.reduceTo(bank,moneyUnit).
				add(augment2.reduceTo(bank,moneyUnit));
	}

}


public class Substract implements Expression {
    
	private Expression augment1;
	private Expression augment2;
	public Substract(Expression augment1,Expression augment2) {
		this.augment1 = augment1;
		this.augment2 = augment2;
		
	}
	@Override
	public Expression add(Expression expression) {
		return new Sum(this, expression);
	}

	@Override
	public Expression substract(Expression expression) {
		return new Substract(this, expression);
	}

	@Override
	public Expression multiply(double multiplier) {
		return new Substract(augment1.multiply(multiplier), 
				augment2.multiply(multiplier));
	}

	@Override
	public Expression divide(double divider) {
		return new Substract(augment1.divide(divider), augment2.divide(divider));
	}

	@Override
	public Expression reduceTo(Bank bank,MoneyUnit moneyUnit) {
		return augment1.reduceTo(bank,moneyUnit).
				substract(augment1.reduceTo(bank,moneyUnit));
	}
}

//currency conversion 
public class Bank {
	
	private Map<Pair,Double> convertors = 
			new HashMap<Bank.Pair, Double>();
	
	public void addExchangeRate(MoneyUnit unit1,MoneyUnit unit2,
			double exchangeRate) {
		
		convertors.put(new Pair(unit1, unit2), 
				exchangeRate);
		
		convertors.put(new Pair(unit2, unit1),
				1/exchangeRate);
		
	}
	
	public Double getExchangeRate(MoneyUnit unit1,MoneyUnit unit2) {
		if(unit1.equals(unit2)) {
			return 1d;
		}
		
		return convertors.
				get(new Pair(unit1, unit2));
		
	}
	
	
	static class Pair<U, V> {
		private U u;
		private V v;
		public Pair(U _u,V _v) {
			this.u = _u;
			this.v = _v;
			
		}
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((u == null) ? 0 : u.hashCode());
			result = prime * result + ((v == null) ? 0 : v.hashCode());
			return result;
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Pair other = (Pair) obj;
			if (u == null) {
				if (other.u != null)
					return false;
			} else if (!u.equals(other.u))
				return false;
			if (v == null) {
				if (other.v != null)
					return false;
			} else if (!v.equals(other.v))
				return false;
			return true;
		}
		
		
	}
	
}

//few utils at last
public class MoneyUtils {
	
	public static Money dollar(double amount) {
		return new Money(amount, MoneyUnit.DOLLAR);
	}
	
	
	public static Money INR(double amount) {
		return new Money(amount, MoneyUnit.INR);
	}
	
	public static Money euro(double amount) {
		return new Money(amount, MoneyUnit.EURO);
	}

}
Advertisements
This entry was posted in Design, Java and tagged , . Bookmark the permalink.

One Response to Java Submission to interfaces!!!

  1. Pingback: Haskell version of currency conversion | Ratn's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s