Java_J2EE_Job_Interview_Companion
.pdf270 How would you go about …?
//...
public class CD extends Goods { //..
//following methods gets called by the template method
public void addToStock() {
//database call logic to store the cd in stock table. System.out.println("CD added to stock : " + this.getDescription());
}
public void applyBarcode() {
//logic to print and apply the barcode to cd.
System.out.println("Bar code applied to cd : " + this.getDescription());
}
public void markRetailPrice() {
//logic to read retail price from the cd table and apply the retail price. System.out.println("Mark retail price for the cd : " + this.getDescription());
}
}
//...
public class Cosmetics extends Goods {
//...
public void addToStock() {
//database call logic to store the cosmetic in stock table. System.out.println("Cosmetic added to stock : " + this.getDescription());
}
public void applyBarcode() {
//logic to print and apply the barcode to cosmetic.
System.out.println("Bar code applied to cosmetic : " + this.getDescription());
}
public void markRetailPrice() {
//logic to read retail price from the cosmetic table and apply the retail price. System.out.println("Mark retail price for the cosmetic : " + this.getDescription());
}
}
Now, let’s see the calling code Shopping:
//...
public class Shopping {
//...
public static void process() throws ItemException {
//...
Item item = null;
for (item = itemIterator.firstItem(); !itemIterator.isDone(); item = itemIterator.nextItem()) {
item.prepareItemForRetail(); |
"); |
System.out.println("----------------------------------- |
|
} |
|
} |
|
} |
|
The output is: |
|
|
|
------------------- prepareItemForRetail() ------------------------------- |
|
Book added to stock : Book - IT |
|
Bar code applied to book : Book - IT |
|
Mark retail price for the book : Book - IT |
|
Scenario: The employees of XYZ Retail are at various levels. In a hierarchy, the general manager has subordinates, and also the sales manager has subordinates. The retail sales staffs have no subordinates and they report to their immediate manager. The company needs functionality to calculate salary at different levels of the hierarchy.
Solution: You can apply the composite design pattern to represent the XYZ Retail company employee hierarchy.
272 |
|
How would you go about …? |
|
|
|
|
boolean hasSubOrdinates |
= false; |
|
if (subordinates != null && subordinates.size() > 0) { |
|
|
hasSubOrdinates = |
true; |
|
} |
|
} |
return hasSubOrdinates; |
|
|
|
|
} |
|
|
/**
* This is the leaf staff employee object. staff do not have any subordinates. */
public class Staff extends Employee {
public Staff(String name, double salary) { super(name, salary);
}
public boolean addEmployee(Employee emp) {
throw new RuntimeException("Improper use of Staff class");
}
public boolean removeEmployee(Employee emp) {
throw new RuntimeException("Improper use of Staff class");
}
protected boolean hasSubordinates() { return false;
}
}
Now, let’s see the calling code Shopping:
//...
public class Shopping {
//..... |
|
|
public static void process() throws ItemException { |
|
|
//.... |
|
|
System.out.println("----------------- |
Employee hierachy & getSalaries() recursively --------- |
"); |
//Employee hierachy |
|
|
Employee generalManager = new Manager("John Smith", 100000.00);
Employee salesManger = new Manager("Peter Rodgers", 80000.00);
Employee logisticsManger = new Manager("Graham anthony", 90000.00);
Employee staffSales1 = new Staff("Lisa john", 40000.00); Employee staffSales2 = new Staff("Pamela watson", 50000.00); salesManger.addEmployee(staffSales1); salesManger.addEmployee(staffSales2);
Employee logisticsTeamLead = new Manager("Cooma kumar", 70000.00);
Employee staffLogistics1 = new Staff("Ben Sampson", 60000.00); Employee staffLogistics2 = new Staff("Vincent Chou", 20000.00); logisticsTeamLead.addEmployee(staffLogistics1); logisticsTeamLead.addEmployee(staffLogistics2);
logisticsManger.addEmployee(logisticsTeamLead);
generalManager.addEmployee(salesManger);
generalManager.addEmployee(logisticsManger);
System.out.println(staffSales1.getName() + "-->" + staffSales1.getSalaries()); System.out.println(staffSales2.getName() + "-->" + staffSales2.getSalaries());
System.out.println("Logistics dept " + " --> " + logisticsManger.getSalaries());
System.out.println("General Manager " + " --> " + generalManager.getSalaries());
}
}
The output is:
|
How would you go about …? |
273 |
|
|
|
--------------------- |
Employee hierachy & getSalaries() recursively ------------- |
|
Lisa john-->40000.0 |
|
|
Pamela watson-- |
>50000.0 |
|
Logistics dept |
--> 240000.0 |
|
General Manager |
--> 510000.0 |
|
Scenario: The purchasing staffs (aka logistics staff) of the XYZ Retail Company need to interact with other subsystems in order to place purchase orders. They need to communicate with their stock control department to determine the stock levels, also need to communicate with their wholesale supplier to determine availability of stock and finally with their bank to determine availability of sufficient funds to make a purchase.
Solution: You can apply the façade design pattern to implement the above scenario.
Façade pattern: The façade pattern provides an interface to large subsystems of classes. A common design goal is to minimize the communication and dependencies between subsystems. One way to achieve this goal is to introduce a façade object that provides a single, simplified interface.
public class StockControl {
public boolean isBelowReorderpoint(Item item) { //logic to evaluate stock level for item return true;
}
}
W i t h o u t f a c a d e
B a n k |
S t o c k C o n t r o l |
W h o l e S a l e r |
W i t h f a c a d e
|
P u r c h a s e |
E v a l u a t i o |
n F a c a d e |
|
B a n k |
S t o c k C o n t r o l |
W h o l e s a l e r |
public class Bank {
public boolean hasSufficientFunds() {
//logic to evaluate if we have sufficient savings goes here return true;
}
}
public class WholeSaler {
public boolean hasSufficientStock(Item item) {
//logic to evaluate if the wholesaler has enough stock goes here return true; //to keep it simple
}
}
/**
How would you go about …? |
275 |
/**
* This is an observer (aka subscriber) interface. This gets notified through its update method. */
public interface Department {
public void update(Item item, int qty);
}
public class LogisticsDepartment implements Department { public void update(Item item, int qty) {
//logic to update department's stock goes here
System.out.println("Logistics has updated its stock for " + item.getDescription() +
" with qty=" + qty);
}
}
public class SalesDepartment implements Department { public void update(Item item, int qty) {
//logic to update department's stock goes here
System.out.println("Sales has updated its stock for " + item.getDescription() +
} |
|
|
|
|
|
" with qty=" + qty); |
|
|
|
|
|
|
|
||
} |
|
|
|
|
|
|
|
|
|
|
-observers |
|
|
|
|
|
«interface» |
«interface» |
|
Observer (aka Subscriber) |
|||
|
StockControl |
|
|
|
Department |
|
|
|
|
|
|
||||
|
|
|
|
||||
|
+addSubscribers() |
|
|
|
+update() |
|
|
|
+removeSubscribers() |
|
|
|
|
|
|
|
|
|
|
|
|
||
|
+notify() |
|
|
|
|
|
|
XYZStockControl
LogisticsDepartment SalesDepartment
+addSubscribers() +removeSubscribers() -subject+update() +update() +notify()
Subject (aka publisher)
/**
*Subject (publisher) class: when stock is updated, notifies all the
*subscribers.
*/
public interface StockControl {
public void notify(Item item, int qty); public void updateStock(Item item, int qty) ;
public boolean addSubscribers(Department dept); public boolean removeSubscribers(Department dept);
}
//… package & import statements
**
*publisher (observable) class: when stock is updated
*notifies all the subscribers.
*/
public class XYZStockControl implements StockControl{
List listSubscribers = new ArrayList(10);
//...
public boolean addSubscribers(Department dept) { return listSubscribers.add(dept);
276 |
How would you go about …? |
}
public boolean removeSubscribers(Department dept) { return listSubscribers.remove(dept);
}
/**
* writes updated stock qty into databases */
public void updateStock(Item item, int qty) { //logic to update an item's stock goes here
notify(item, qty); //notify subscribers that with the updated stock info.
}
public void notify(Item item, int qty) {
int noOfsubscribers = listSubscribers.size(); for (int i = 0; i < noOfsubscribers; i++) {
Department dept = (Department) listSubscribers.get(i); dept.update(item, qty);
}
}
}
Now, let’s see the calling code or class Shopping:
// package & import statements
public class Shopping { //...............
public static void process() throws ItemException {
//......... |
|
|
//---------------------- |
observer design pattern------------------------------------------- |
"); |
System.out.println("-------------------- |
notify stock update---------------------------- |
|
Department deptLogistics = new LogisticsDepartment(); //observer/subscriber |
|
|
Department salesLogistics = new SalesDepartment(); //observer/subscriber |
|
|
StockControl stockControl = new XYZStockControl();//observable/publisher |
|
|
//let's register subscribers with the publisher |
|
|
stockControl.addSubscribers(deptLogistics); |
|
|
stockControl.addSubscribers(salesLogistics); |
|
//let's update the stock value of the publisher
for (item = itemIterator.firstItem(); !itemIterator.isDone(); item = itemIterator.nextItem()) { if (item instanceof CD) {
stockControl.updateStock(item, 25); } else if (item instanceof Book){
stockControl.updateStock(item, 40);
}
else {
stockControl.updateStock(item, 50);
}
}
}
}
The output is:
--------------------notify stock update----------------------------
Logistics has updated its stock for Book - IT with qty=40 Sales has updated its stock for Book - IT with qty=40 Logistics has updated its stock for CD - JAZZ with qty=25 Sales has updated its stock for CD - JAZZ with qty=25
Logistics has updated its stock for Cosmetics - Lipstick with qty=50 Sales has updated its stock for Cosmetics - Lipstick with qty=50 Logistics has updated its stock for CD - JAZZ IMPORTED with qty=25 Sales has updated its stock for CD - JAZZ IMPORTED with qty=25
Scenario: The stock control staff require a simplified calculator, which enable them to add and subtract stock counted and also enable them to undo and redo their operations. This calculator will assist them with faster processing of stock counting operations.
Solution: This can be achieved by applying the command design pattern as shown below:
278 How would you go about …?
public void redo(int noOfLevels) {
int noOfCommands = listCommands.size(); for (int i = 0; i < noOfLevels; i++) {
if (current < noOfCommands) {
((Command) listCommands.get(current++)).execute();
}
}
}
/**
* perform undo operations */
public void undo(int noOfLevels) {
for (int i = 0; i < noOfLevels; i++) { if (current > 0) {
((Command) listCommands.get(--current)).unexecute();
}
}
}
}
<<abstract>> Employee
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CalculatorCommand |
|
|
||
|
|
|
|
Calculator |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+execute() |
|
|
||
|
|
|
|
+calculate() |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
+unexecute() |
|
|
||||
|
|
|
|
Staff |
|
|
|
|
|
«interface» |
|
Command, whichdecouples |
||
Invoker |
|
|
|
1 |
* |
|
Command |
|
the invoker fromthe receiver. |
|||||
|
|
|
|
+compute() |
|
|
|
|
|
+execute() |
|
|
||
|
|
|
|
+redo() |
|
|
|
|
|
+unexecute() |
|
|
||
|
|
|
|
+undo() |
|
|
|
|
|
|
|
|
|
|
Receiver |
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**
* actual receiver of the command who performs calculation */
public class Calculator { private int total = 0;
/**
* calculates. */
public void calculate(char operator, int operand) { switch (operator) {
case '+':
total += operand; break;
case '-':
total -= operand; break;
}
System.out.println("Total = " + total);
How would you go about …? |
279 |
}
}
/**
* command interface */
public interface Command { public void execute(); public void unexecute();
}
/**
* calculator command, which decouples the receiver Calculator from the invoker Staff */
public class CalculatorCommand implements Command { private Calculator calc = null;
private char operator; private int operand;
public CalculatorCommand(Calculator calc, char operator, int operand) { this.calc = calc;
this.operator = operator; this.operand = operand;
}
public void execute() { calc.calculate(operator, operand);
}
public void unexecute() { calc.calculate(undoOperand(operator), operand);
}
private char undoOperand(char operator) { char undoOperator = ' ';
switch (operator) { case '+':
undoOperator = '-'; break;
case '-': undoOperator = '+'; break;
}
return undoOperator;
}
}
Now, let’s see the calling code class Shopping:
//..............
public class Shopping {
//...........
public static void process() throws ItemException {
//------------------------------- |
command design pattern----------------------------------- |
"); |
System.out.println("------------ |
Calculator with redo & undo operations----------------------- |
|
Staff stockControlStaff = new Staff("Vincent Chou"); |
|
|
stockControlStaff.compute('+',10);//10 |
|
|
stockControlStaff.compute('-',5);//5 |
|
|
stockControlStaff.compute('+',10);//15 |
|
|
stockControlStaff.compute('-',2);//13 |
|
|
//lets try our undo operations |
undo operation : 1 level |
"); |
System.out.println("--------------- |
||
stockControlStaff.undo(1); |
undo operation : 2 levels |
"); |
System.out.println("--------------- |
||
stockControlStaff.undo(2); |
|
|
//lets try our redo operations |
redo operation : 2 levels |
"); |
System.out.println("--------------- |
||
stockControlStaff.redo(2); |
|
|