Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Java_J2EE_Job_Interview_Companion

.pdf
Скачиваний:
21
Добавлен:
13.05.2015
Размер:
14.25 Mб
Скачать

260 How would you go about …?

}

double totalTax = 0.0;

Iterator it = listItems.iterator(); while (it.hasNext()) {

Item item = (Item) it.next(); totalTax += item.getExtendedTax();

}

return totalTax;

}

/**

* calculates total price on the items in the built basket

*/

public double calculateTotal() throws ItemException { if (listItems == null) {

throw new ItemException("No items in the basket");

}

double total = 0.0;

Iterator it = listItems.iterator(); while (it.hasNext()) {

Item item = (Item) it.next();

total += item.getExtendedTaxPrice();

}

return total;

}

/**

* prints individual prices of the items in the built basket

*/

public void printExtendedTaxedPrice() throws ItemException { if (listItems == null) {

throw new ItemException("No items in the basket");

}

double totalTax = 0.0;

Iterator it = listItems.iterator(); while (it.hasNext()) {

Item item = (Item) it.next();

System.out.println(item + "" + item.getExtendedTaxPrice());

}

}

public Iterator getIterator() { return listItems.iterator();

}

}

Finally, the calling-code, which makes use of our shopping basket builder pattern to build the shopping basket step-by- step and also calculates the taxes and the grand total for the items in the shopping basket.

…//package & import statements

public class Shopping { /**

*Class with main(String[] args) method which initially gets loaded by the

*class loader. Subsequent classes are loaded as they are referenced in the program.

*/

public static void main(String[] args) throws ItemException { process();

}

public static void process() throws ItemException {

//------creational patterns: singleton, factory method and builder design patterns------

System.out.println("----create a shopping basket with items ---"); //Shopping basket using the builder pattern

ItemBuilder builder = new ShoppingBasketBuilder(); //build basket of items using a builder pattern

builder.buildBasket(Item.TYPE_BOOK, "Book - IT", 1, 12.00); builder.buildBasket(Item.TYPE_CD, "CD - JAZZ", 1, 15.00); builder.buildBasket(Item.TYPE_COSMETICS, "Cosmetics - Lipstick", 1, 1.0);

//let’s print prices and taxes of this built basket double totalTax = builder.calculateTotalTax(); builder.printExtendedTaxedPrice(); System.out.println("Sales Taxes: " + totalTax);

 

How would you go about …?

261

System.out.println("Grand

Total: " +

builder.calculateTotal());

 

System.out.println("-----

After adding

an imported CD to the basket ----");

 

//Say now customer decides to buy an additional imported CD builder.buildBasket(Item.TYPE_CD_IMPORTED, "CD - JAZZ IMPORTED", 1, 15.00);

//lets print prices and taxes of this built basket with imported CD added totalTax = builder.calculateTotalTax(); builder.printExtendedTaxedPrice();

System.out.println("Sales Taxes: " + totalTax); System.out.println("Grand Total: " + builder.calculateTotal());

}

}

Running the above code produces an output of:

----create a shopping basket with items ---

1

Book

- IT

: 12.0

1

CD -

JAZZ

: 16.5

1

Cosmetics

- Lipstick : 1.1

Sales Taxes: 1.6

Grand Total:

29.6

----- After

adding an imported CD to the basket ----

1

Book

- IT

: 12.0

1

CD -

JAZZ

: 16.5

1

Cosmetics

- Lipstick : 1.1

1

CD -

JAZZ

IMPORTED : 17.25

Sales Taxes: 3.85

Grand Total:

46.85

Scenario: The XYZ Retail wants to evaluate a strategy to determine items with description longer than 15 characters because it won’t fit in the invoice and items with description starting with “CD” to add piracy warning label.

Solution: You can implement evaluating a strategy to determine items with description longer than 15 characters and description starting with “CD” applying the strategy design pattern as shown below:

Strategy pattern: The Strategy pattern lets you build software as a loosely coupled collection of interchangeable parts, in contrast to a monolithic, tightly coupled system. Loose coupling makes your software much more extensible, maintainable, and reusable. The main attribute of this pattern is that each strategy encapsulates algorithms i.e. it is not data based but algorithm based. Refer Q12, Q64 in Java section.

Example: You can draw borders around almost all Swing components, including panels, buttons, lists, and so on. Swing provides numerous border types for its components: bevel, etched, line, titled, and even compound. JComponent class, which acts as the base class for all Swing components by implementing functionality common to all Swing components, draws borders for Swing components, using strategy pattern.

public interface CheckStrategy { public boolean check(String word);

}

public class LongerThan15 implements CheckStrategy public static final int LENGTH = 15; //constant

public boolean check(String description) { if (description == null)

return false;

else

return description.length() > LENGTH;

}

}

{

LongerThan15

«interface»

StartsWithCD

 

CheckStrategy

 

+check() : boolean

+check() : boolean

+check() : boolean

 

public class StartsWithCD implements CheckStrategy { public static final String STARTS_WITH = "cd";

public boolean check(String description) { String s = description.toLowerCase();

if (description == null || description.length() == 0) return false;

else

262

How would you go about …?

return s.startsWith(STARTS_WITH);

}

}

Scenario: The XYZ retail has decided to count the number of items, which satisfy the above strategies.

Solution: You can apply the decorator design pattern around your strategy design pattern. Refer Q24 in Java section for the decorator design pattern used in java.io.*. The decorator acts as a wrapper around the CheckStrategy objects where by call the check(…) method on the CheckStrategy object and if it returns true then increment the counter. The decorator design pattern can be used to provide additional functionality to an object of some kind. The key to a decorator is that a decorator "wraps" the object decorated and looks to a client exactly the same as the object wrapped. This means that the decorator implements the same interface as the object it decorates.

Decorator design pattern: You can think of a decorator as a shell around the object decorated. The decorator catches any message that a client sends to the object instead. The decorator may apply some action and then pass the message it received on to the decorated object. That object probably returns a value to the decorator which may again apply an action to that result, finally sending the (perhaps-modified) result to the original client. To the client the decorator is invisible. It just sent a message and got a result. However the decorator had two chances to enhance the result returned.

public class CountDecorator implements CheckStrategy {

private CheckStrategy cs = null;

 

LongerThan15

«interface»

*

StartsWithCD

private int count = 0;

 

 

CheckStrategy

 

 

public CountDecorator(CheckStrategy cs) {

+check() : boolean

+check() : boolean

 

+check() : boolean

 

 

this.cs = cs;

 

 

 

 

 

}

 

 

CountDecorator

 

 

 

 

 

 

 

public boolean check(String description) {

 

 

 

 

boolean isFound = cs.check(description);

 

+check() : boolean 1

 

 

if (isFound)

 

 

 

 

 

this.count++;

 

 

 

 

 

return isFound;

There is a subtle difference between the decorator pattern and the proxy

}

pattern is that, the main intent of the decorator pattern is to enhance the

public int count() {

functionality of the target object whereas the main intent of the proxy pattern

is to control access to the target object.

 

 

return this.count;

 

 

 

 

 

}

A decorator object’s interface must conform to the public void reset() { interface of the component it decorates

this.count = 0;

}

}

Now, let’s see the calling class Shopping:

//…. package & import statements

public class Shopping {

//...

public static void process() throws ItemException {

...

Iterator it = builder.getIterator(); boolean bol = false;

CheckStrategy strategy = null;

it = builder.getIterator(); //for starting with CD strategy = new StartsWithCD();

strategy = new CountDecorator(strategy); while (it.hasNext()) {

Item item = (Item) it.next();

bol = strategy.check(item.getDescription()); System.out.println("\n" + item.getDescription() + " --> " + bol);

}

System.out.println("No of descriptions starts with CD -->" +

((CountDecorator) strategy).count());

it = builder.getIterator();

 

How would you go about …?

263

//longer

than 15 charecters

 

strategy

= new LongerThan15();

 

strategy

= new CountDecorator(strategy);

 

while (it.hasNext()) {

 

Item

item = (Item) it.next();

 

bol = strategy.check(item.getDescription()); System.out.println("\n" + item.getDescription() + " --> " + bol);

}

System.out.println("No of descriptions longer than 15 characters -->" +

((CountDecorator) strategy).count());

}

}

Running the above code produces an output of:

----count

---item description starting with 'cd' or longer than 15 characters

Book--------------------

- IT

> false

description satarting with cd ----------------------------

 

 

 

CD -

JAZZ

--> true

> false

 

 

Cosmetics

- Lipstick

 

 

CD -

JAZZ

IMPORTED --

> true

>2

 

No of descriptions starts with CD --

 

Book-------------------

- IT

> false

description longer than 15 characters -----------------------

 

 

 

CD -

JAZZ

--> false

> true

 

 

Cosmetics

- Lipstick

 

 

CD -

JAZZ

IMPORTED --

> true

 

>2

No of descriptions longer than 15 characters --

Scenario: So far so good, for illustration purpose if you need to adapt the strategy class to the CountDecorator class so that you do not have to explicitly cast your strategy classes to CountDecorator as shown in bold arrow in the class Shopping. We can overcome this by slightly rearranging the classes. The class CountDecorator has two additional methods count() and reset(). If you only just add these methods to the interface CheckStrategy then the classes LongerThan15 and StartsWithCD should provide an implementation for these two methods. These two methods make no sense in these two classes.

Solution: So, to overcome this you can introduce an adapter class named CheckStrategyAdapter, which just provides a bare minimum default implementation. Adapter design pattern

public interface CheckStrategy {

public boolean check(String word); public int count();

public void reset();

}

/**

*This is an adapter class which provides default implementations to be extended not to be used and

*facilitates its subclasses to be adapted to each other. Throws an unchecked exception to indicate

*improper use.

*/

public class CheckStrategyAdapter implements CheckStrategy { public boolean check(String word) {

throw new RuntimeException("Improper use of CheckStrategyAdapter

class method check(String word)" );

}

public int count() {

throw new RuntimeException("Improper use of CheckStrategyAdapter class method count()" );

}

public void reset() {

throw new RuntimeException("Improper use of CheckStrategyAdapter class method reset()" );

}

}

public class LongerThan15 extends CheckStrategyAdapter { public static final int LENGTH = 15;

public boolean check(String description) { if (description == null)

return false;

264

How would you go about …?

else

return description.length() > LENGTH;

}

}

public class StartsWithCD extends CheckStrategyAdapter { public static final String STARTS_WITH = "cd";

public boolean check(String description) { String s = description.toLowerCase();

if (description == null || description.length() == 0) return false;

else

return s.startsWith(STARTS_WITH);

}

}

public class CountDecorator extends CheckStrategyAdapter {

private CheckStrategy cs = null; private int count = 0;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public CountDecorator(CheckStrategy cs) {

 

 

 

 

 

«interface»

 

 

 

 

 

 

 

this.cs = cs;

 

 

 

 

 

 

 

 

 

 

 

CheckStrategy

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

1

 

 

+check() : boolean

 

 

 

 

 

 

 

public boolean check(String description) {

 

 

 

 

 

 

+count() : int

 

 

 

 

 

 

 

 

1

 

 

 

 

+reset()

 

 

 

 

 

 

 

boolean isFound = cs.check(description);

 

 

 

 

 

 

 

 

 

 

 

LongerThan15

 

if (isFound){

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

this.count++;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CountDecorator

 

 

CheckStrategyAdapter

 

 

 

 

 

 

}

 

 

 

 

 

 

 

+check() : boolean

 

return isFound;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StartsWuthCD

 

 

 

+check() : boolean

 

 

+check() : boolean

 

 

public int count() {

 

 

+count() : int

 

 

+count() : int

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+reset()

 

 

 

+reset()

 

 

 

 

 

 

return this.count;

 

 

 

 

 

 

 

 

+check() : boolean

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public void reset() {

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

this.count = 0;

Adapter provides default implementation, so that it can be extended to provide specific implementation.

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

Now, let’s see the revised calling class Shopping:

//

...package

& import statements

 

 

 

 

public class

Shopping {

 

 

 

 

 

//......

 

 

 

 

 

 

public static void process() throws ItemException {

 

 

 

 

//--------------------------

Strategy and decorator design pattern--------------------------

 

 

System.out.println("-count item description starting with 'cd'or longer than 15 characters -");

 

Iterator

it = builder.getIterator();

 

 

 

 

boolean bol = false;

 

 

 

 

 

CheckStrategy strategy = null;

description satarting with cd

");

 

System.out.println("----------------

 

it = builder.getIterator();

 

 

 

 

 

//for starting with CD

 

 

 

 

 

strategy

= new StartsWithCD();

 

 

 

 

 

strategy

= new CountDecorator(strategy);

 

 

 

 

while (it.hasNext()) {

 

 

 

 

 

Item

item = (Item) it.next();

 

 

 

 

 

bol = strategy.check(item.getDescription());

> " + bol);

 

 

System.out.println(item.getDescription() + " --

 

 

}

 

 

 

 

 

 

System.out.println("No of descriptions starts with CD --

>" + strategy.count());

 

 

System.out.println("--------------

description longer than 15 characters ------------------

");

 

it = builder.getIterator();

 

 

 

 

 

//longer

than 15 charecters

 

 

 

 

 

strategy

= new LongerThan15();

 

 

 

 

 

strategy

= new CountDecorator(strategy);

 

 

 

 

 

 

How would you go about …?

265

 

 

 

 

 

 

while

(it.hasNext()) {

 

 

 

 

Item item = (Item) it.next();

 

 

 

bol = strategy.check(item.getDescription());

> " + bol);

 

System.out.println(item.getDescription() + " --

 

}

 

 

 

 

 

>" + strategy.count());

System.out.println("No of descriptions longer than 15 characters --

}

 

 

 

 

 

 

}

 

 

 

 

 

 

The output is:

 

 

 

 

 

 

 

----count

item description starting with 'cd'or longer than 15 characters ---

Book--------------------- IT

> false

description satarting with cd ----------------------------

 

 

 

 

 

 

 

CD - JAZZ

--> true

> false

 

 

 

 

Cosmetics

- Lipstick

 

 

 

 

CD - JAZZ

IMPORTED --

> true

>2

 

 

 

No of descriptions starts with CD

 

 

 

-------------------

 

description longer than 15 characters -----------------------

 

Book - IT

--> false

 

 

 

 

 

CD - JAZZ

--> false

> true

 

 

 

 

Cosmetics

- Lipstick

 

 

 

 

CD - JAZZ

IMPORTED --

> true

 

>2

 

 

No of descriptions longer than 15 characters --

 

 

Scenario: The XYZ Retail also requires a piece of code, which performs different operations depending on the type of item. If the item is an instance of CD then you call a method to print its catalog number. If the item is an instance of Cosmetics then you call a related but different method to print its color code. If the item is an instance of Book then you call a separate method to print its ISBN number. One way of implementing this is using the Java constructs instanceof and explicit type casting as shown below:

it = builder.getIterator();

while(it.hasNext(); ) { String name = null;

Item item = (Item)iter.next();

if(item instanceof CD) {

((CD) item). markWithCatalogNumber(); } else if (item instanceof Cosmetics) {

((Cosmetics) item). markWithColourCode (); } else if (item instanceof Book) {

((Book) item). markWithISBNNumber();

}

}

Problem: The manipulation of a collection of polymorphic objects with the constructs typecasts and instanceof as shown above can get messy and unmaintainable with large elseif constructs and these constructs in frequently accessed methods/ loops can adversely affect performance. Solution: You can apply the visitor design pattern to avoid using these typecast and “instanceof” constructs as shown below:

Visitor pattern: The visitor pattern makes adding new operations easy and all the related operations are localized in a visitor. The visitor pattern allows you to manipulate a collection of polymorphic objects without the messy and unmaintainable typecasts and instanceof operations. Visitor pattern allows you to add new operations, which affect a class hierarchy without having to change any of the classes in the hierarchy. For example we can add a GoodsDebugVisitor class to have the visitor just print out some debug information about each item visited etc. In fact you can write any number of visitor classes for the Goods hierarchy e.g. GoodsLabellingVisitor, GoodsPackingVisitor etc.

public interface Item { //...

public void accept(ItemVisitor visitor);

}

public interface ItemVisitor { public void visit (CD cd);

public void visit (Cosmetics cosmetics); public void visit (Book book);

}

266

«interface»

ItemVisitor

+visit(CD cd)() +visit(Book book)()

+visit(Cosmetics cosmetics)()

GoodsLabellingVisitor

+visit(CD cd)() +visit(Book book)()

+visit(Cosmetics cosmetics()

How would you go about …?

<<abstract>>

«interface»

Goods

Item

 

+accept(ItemVisitor visitor)()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CD

 

Book

 

Cosmetics

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+accept(ItemVisitor visitor)()

 

 

 

+accept(ItemVisitor visitor)()

 

+accept(ItemVisitor visitor)()

 

 

 

 

 

 

 

 

 

 

 

/**

*visitor class which calls different methods depending

*on type of item.

*/

public class GoodsLabellingVisitor implements ItemVisitor {

public void visit(CD cd) { markWithCatalogNumber(cd);

}

public void visit(Cosmetics cosmetics) { markWithColorNumber(cosmetics);

}

public void visit(Book book) { markWithISBNNumber(book);

}

private void markWithCatalogNumber(CD cd) { System.out.println("Catalog number for : " + cd.getDescription());

}

private void markWithColorNumber(Cosmetics cosmetics) { System.out.println("Color number for : " + cosmetics.getDescription());

}

public void markWithISBNNumber(Book book) {

System.out.println("ISBN number for : " + book.getDescription());

}

}

public class CD extends Goods { //...

public void accept(ItemVisitor visitor) { visitor.visit(this);

}

}

public class Book extends Goods { //...

public void accept(ItemVisitor visitor) { visitor.visit(this);

}

}

public class Cosmetics extends Goods {

//...

How would you go about …?

267

public void accept(ItemVisitor visitor) { visitor.visit(this);

}

}

Now, let’s see the calling code or class Shopping:

//... package and import statements

public class Shopping {

public static void process() throws ItemException {

//visitor pattern example, no messy instanceof and typecast constructs it = builder.getIterator();

ItemVisitor visitor = new GoodsLabellingVisitor (); while (it.hasNext()) {

Item item = (Item) it.next(); item.accept(visitor);

}

}

}

The output is:

---- markXXXX(): avoid huge if else statements, instanceof & type casts --------

ISBN number for : Book - IT Catalog number for : CD - JAZZ

Color number for : Cosmetics - Lipstick Catalog number for : CD - JAZZ IMPORTED

Scenario: The XYZ Retail would like to have a functionality to iterate through every second or third item in the basket to randomly collect some statistics on price.

Solution: This can be implemented by applying the iterator design pattern.

Iterator pattern: Provides a way to access the elements of an aggregate object without exposing its underlying implementation.

//… package and import statements

public interface ItemBuilder { //..

public com.item.Iterator getItemIterator();

}

package com.item;

public interface Iterator { public Item nextItem(); public Item previousItem(); public Item currentItem(); public Item firstItem(); public Item lastItem(); public boolean isDone();

public void setStep(int step);

}

«interface»

«interface»

Iterator

ItemBuilder

+currentItem()()

+getItemIterator()

+nextItem()

 

+previousItem()

 

+firstItem()

 

+lastItem()

//… package and import statements

 

ItemsIterator

public class ShoppingBasketBuilder

ShoppingBasketBuilder

 

implements ItemBuilder {

 

 

private List listItems = null;

+getItemIterator()

+currentItem()

public Iterator getIterator() {

+nextItem()

 

+previousItem()

return listItems.iterator();

 

}

 

+firstItem()

public com.item.Iterator getItemIterator() {

+lastItem()

return new ItemsIterator();

 

 

}

 

 

268

How would you go about …?

/**

* inner class which iterates over basket of items */

class ItemsIterator implements com.item.Iterator { private int current = 0;

private int step = 1;

public Item nextItem() { Item item = null; current += step;

if (!isDone()) {

item = (Item) listItems.get(current);

}

return item;

}

public Item previousItem() { Item item = null;

current -= step; if (!isDone()) {

item = (Item) listItems.get(current);

}

return item;

}

public Item firstItem() { current = 0;

return (Item) listItems.get(current);

}

public Item lastItem() {

current = listItems.size() - 1; return (Item) listItems.get(current);

}

public boolean isDone() {

return current >= listItems.size() ? true : false;

}

public Item currentItem() { if (!isDone()) {

return (Item) listItems.get(current);

}else { return null;

}

}

public void setStep(int step) { this.step = step;

}

}

}

Now, let’s see the calling code Shopping:

//… package & import statements

public class Shopping { //..

public static void process() throws ItemException {

//Iterator pattern example, inner implementations of ShopingBasketBuilder is protected. com.item.Iterator itemIterator = builder.getItemIterator();

//say we want to traverse through every second item in the basket itemIterator.setStep(2);

Item item = null;

for (item = itemIterator.firstItem(); !itemIterator.isDone(); item = itemIterator.nextItem()) { System.out.println("nextItem:" + item.getDescription() + "==>" + item.getExtendedTaxPrice());

}

item = itemIterator.lastItem();

System.out.println("lastItem: " + item.getDescription() + "==> " + item.getExtendedTaxPrice());

How would you go about …?

269

item = itemIterator.previousItem();

System.out.println("previousItem:" + item.getDescription()+ "=>" + item.getExtendedTaxPrice());

}

}

The output is:

--------------- steps through every 2nd item in the basket -----------------------

nextItem: Book - IT ====> 12.0

nextItem: Cosmetics - Lipstick ====> 1.1 lastItem: CD - JAZZ IMPORTED ====> 17.25 previousItem : CD - JAZZ====>16.5

Scenario: The XYZ Retail buys the items in bulk from warehouses and sells them in their retail stores. All the items sold need to be prepared for retail prior to stacking in the shelves for trade. The preparation involves 3 steps for all types of items, i.e. adding the items to stock in the database, applying barcode to each item and finally marking retail price on the item. The preparation process is common involving 3 steps but each of these individual steps is specific to type of item i.e. Book, CD, and Cosmetics.

Solution: The above functionality can be implemented applying the template method design pattern as shown below:

Template method pattern: When you have a sequence of steps to be processed within a method and you want to defer some of the steps to its subclass then you can use a template method pattern. So the template method lets the subclass to redefine some of the steps.

Example Good example of this is the process() method in the Struts RequestProcessor class, which executes a

sequence of processXXXX(…) methods allowing the subclass to override some of the methods when required. Refer

Q110 in Enterprise section.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<<abstract>>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Goods

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public abstract class Goods implements Item {

 

+prepareItemForRetail()

 

 

 

addToStock() --> abstract

//...

 

 

 

 

 

+addToStock()

 

 

 

applyBarcode --> abstract

/**

 

 

 

 

 

+applyBarcode()

 

 

 

markRetailPrice --> abstract

 

 

 

 

 

 

 

 

 

 

 

 

+markRetailPrice()

 

 

 

 

 

 

* The template method

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public void prepareItemForRetail() {

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

addToStock();

 

CD

 

Book

 

 

 

Cosmetics

 

applyBarcode();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

markRetailPrice();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

 

 

+addToStock()

 

+addToStock()

 

+addToStock()

 

public abstract void addToStock();

 

 

+applyBarcode()

 

+applyBarcode()

 

+applyBarcode()

 

 

+markRetailPrice()

 

+markRetailPrice()

 

+markRetailPrice()

 

public abstract void applyBarcode();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public abstract void markRetailPrice();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

public class Book extends Goods {

 

 

 

 

 

 

 

 

 

 

 

 

 

//..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//following methods gets called by the template method

public void addToStock() {

//database call logic to store the book in stock table. System.out.println("Book added to stock : " + this.getDescription());

}

public void applyBarcode() {

//logic to print and apply the barcode to book.

System.out.println("Bar code applied to book : " + this.getDescription());

}

public void markRetailPrice() {

//logic to read retail price from the book table and apply the retail price. System.out.println("Mark retail price for the book : " + this.getDescription());

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]