Reformat business-delegate, callback, chain, command, composite, dao, decorator & dependency-injection patterns.

This commit is contained in:
Ankur Kaushal 2015-11-01 18:48:43 -05:00
parent 3af06a3a3a
commit 449340bd2b
54 changed files with 698 additions and 700 deletions

View File

@ -2,23 +2,25 @@ package com.iluwatar.business.delegate;
/** /**
* *
* The Business Delegate pattern adds an abstraction layer between the presentation and business tiers. * The Business Delegate pattern adds an abstraction layer between the presentation and business
* By using the pattern we gain loose coupling between the tiers. The Business Delegate encapsulates * tiers. By using the pattern we gain loose coupling between the tiers. The Business Delegate
* knowledge about how to locate, connect to, and interact with the business objects that make up * encapsulates knowledge about how to locate, connect to, and interact with the business objects
* the application. * that make up the application.
* <p> * <p>
* Some of the services the Business Delegate uses are instantiated directly, and some can be retrieved * Some of the services the Business Delegate uses are instantiated directly, and some can be
* through service lookups. The Business Delegate itself may contain business logic too potentially tying * retrieved through service lookups. The Business Delegate itself may contain business logic too
* together multiple service calls, exception handling, retrying etc. * potentially tying together multiple service calls, exception handling, retrying etc.
* <p> * <p>
* In this example the client ({@link Client}) utilizes a business delegate ({@link BusinessDelegate}) to execute a task. * In this example the client ({@link Client}) utilizes a business delegate (
* The Business Delegate then selects the appropriate service and makes the service call. * {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
* service and makes the service call.
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -2,8 +2,9 @@ package com.iluwatar.callback;
/** /**
* *
* Callback pattern is more native for functional languages where functions are treated as first-class citizens. * Callback pattern is more native for functional languages where functions are treated as
* Prior to Java 8 callbacks can be simulated using simple (alike command) interfaces. * first-class citizens. Prior to Java 8 callbacks can be simulated using simple (alike command)
* interfaces.
* *
*/ */
public class App { public class App {

View File

@ -11,5 +11,4 @@ public class SimpleTask extends Task {
public void execute() { public void execute() {
System.out.println("Perform some important activity and after call the callback method."); System.out.println("Perform some important activity and after call the callback method.");
} }
} }

View File

@ -5,8 +5,8 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
/** /**
* Add a field as a counter. Every time the callback method is called increment this * Add a field as a counter. Every time the callback method is called increment this field. Unit
* field. Unit test checks that the field is being incremented. * test checks that the field is being incremented.
* *
* Could be done with mock objects as well where the call method call is verified. * Could be done with mock objects as well where the call method call is verified.
*/ */

View File

@ -2,30 +2,29 @@ package com.iluwatar.chain;
/** /**
* *
* The Chain of Responsibility pattern is a design pattern consisting of command * The Chain of Responsibility pattern is a design pattern consisting of command objects and a
* objects and a series of processing objects. Each processing object contains * series of processing objects. Each processing object contains logic that defines the types of
* logic that defines the types of command objects that it can handle; the rest are * command objects that it can handle; the rest are passed to the next processing object in the
* passed to the next processing object in the chain. A mechanism also exists for * chain. A mechanism also exists for adding new processing objects to the end of this chain.
* adding new processing objects to the end of this chain.
* <p> * <p>
* In this example we organize the request handlers ({@link RequestHandler}) into a * In this example we organize the request handlers ({@link RequestHandler}) into a chain where each
* chain where each handler has a chance to act on the request on its turn. Here * handler has a chance to act on the request on its turn. Here the king ({@link OrcKing}) makes
* the king ({@link OrcKing}) makes requests and the military orcs ({@link OrcCommander}, * requests and the military orcs ({@link OrcCommander}, {@link OrcOfficer}, {@link OrcSoldier})
* {@link OrcOfficer}, {@link OrcSoldier}) form the handler chain. * form the handler chain.
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
OrcKing king = new OrcKing(); OrcKing king = new OrcKing();
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle")); king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
"torture prisoner"));
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
} }

View File

@ -2,21 +2,22 @@ package com.iluwatar.command;
/** /**
* *
* The Command pattern is a behavioral design pattern in which an object is used to encapsulate all information * The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
* needed to perform an action or trigger an event at a later time. This information includes the method name, * information needed to perform an action or trigger an event at a later time. This information
* the object that owns the method and values for the method parameters. * includes the method name, the object that owns the method and values for the method parameters.
* <p> * <p>
* Four terms always associated with the command pattern are command, receiver, invoker and client. A command * Four terms always associated with the command pattern are command, receiver, invoker and client.
* object (spell) knows about the receiver (target) and invokes a method of the receiver. Values for parameters of * A command object (spell) knows about the receiver (target) and invokes a method of the receiver.
* the receiver method are stored in the command. The receiver then does the work. An invoker object (wizard) * Values for parameters of the receiver method are stored in the command. The receiver then does
* knows how to execute a command, and optionally does bookkeeping about the command execution. The invoker * the work. An invoker object (wizard) knows how to execute a command, and optionally does
* does not know anything about a concrete command, it knows only about command interface. Both an invoker object * bookkeeping about the command execution. The invoker does not know anything about a concrete
* and several command objects are held by a client object (app). The client decides which commands to execute at * command, it knows only about command interface. Both an invoker object and several command
* which points. To execute a command, it passes the command object to the invoker object. * objects are held by a client object (app). The client decides which commands to execute at which
* points. To execute a command, it passes the command object to the invoker object.
* <p> * <p>
* In other words, in this example the wizard casts spells on the goblin. The wizard keeps track of the previous * In other words, in this example the wizard casts spells on the goblin. The wizard keeps track of
* spells cast, so it is easy to undo them. In addition, the wizard keeps track of the spells undone, so they * the previous spells cast, so it is easy to undo them. In addition, the wizard keeps track of the
* can be redone. * spells undone, so they can be redone.
* *
* *
*/ */
@ -24,6 +25,7 @@ public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -31,8 +31,8 @@ public abstract class Target {
public abstract String toString(); public abstract String toString();
public void printStatus() { public void printStatus() {
System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(),
getSize(), getVisibility())); getVisibility()));
System.out.println(); System.out.println();
} }
} }

View File

@ -13,8 +13,7 @@ public class Wizard {
private Deque<Command> undoStack = new LinkedList<>(); private Deque<Command> undoStack = new LinkedList<>();
private Deque<Command> redoStack = new LinkedList<>(); private Deque<Command> redoStack = new LinkedList<>();
public Wizard() { public Wizard() {}
}
public void castSpell(Command command, Target target) { public void castSpell(Command command, Target target) {
System.out.println(this + " casts " + command + " at " + target); System.out.println(this + " casts " + command + " at " + target);

View File

@ -1,20 +1,21 @@
package com.iluwatar.composite; package com.iluwatar.composite;
/** /**
* The Composite pattern is a partitioning design pattern. The Composite pattern * The Composite pattern is a partitioning design pattern. The Composite pattern describes that a
* describes that a group of objects is to be treated in the same way as a single * group of objects is to be treated in the same way as a single instance of an object. The intent
* instance of an object. The intent of a composite is to "compose" objects into * of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.
* tree structures to represent part-whole hierarchies. Implementing the Composite * Implementing the Composite pattern lets clients treat individual objects and compositions
* pattern lets clients treat individual objects and compositions uniformly. * uniformly.
* <p> * <p>
* In this example we have sentences composed of words composed of letters. All of * In this example we have sentences composed of words composed of letters. All of the objects can
* the objects can be treated through the same interface ({@link LetterComposite}). * be treated through the same interface ({@link LetterComposite}).
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -22,5 +22,4 @@ public class Letter extends LetterComposite {
protected void printThisAfter() { protected void printThisAfter() {
// nop // nop
} }
} }

View File

@ -15,20 +15,19 @@ public class Messenger {
List<Word> words = new ArrayList<Word>(); List<Word> words = new ArrayList<Word>();
words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter(
new Letter('e'), new Letter('r'), new Letter('e')))); 'r'), new Letter('e'))));
words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
new Letter('e'), new Letter('r'), new Letter('e')))); 'r'), new Letter('e'))));
words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
words.add(new Word(Arrays.asList(new Letter('a')))); words.add(new Word(Arrays.asList(new Letter('a'))));
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter(
new Letter('i'), new Letter('p')))); 'p'))));
words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter(
new Letter('e'), new Letter('r'), new Letter('e')))); 'r'), new Letter('e'))));
words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
words.add(new Word(Arrays.asList(new Letter('a')))); words.add(new Word(Arrays.asList(new Letter('a'))));
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y'))));
new Letter('y'))));
return new Sentence(words); return new Sentence(words);
@ -38,18 +37,18 @@ public class Messenger {
List<Word> words = new ArrayList<Word>(); List<Word> words = new ArrayList<Word>();
words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter(
new Letter('c'), new Letter('h')))); 'h'))));
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter(
new Letter('n'), new Letter('d')))); 'd'))));
words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter(
new Letter('u'), new Letter('r'), new Letter('s')))); 'r'), new Letter('s'))));
words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter(
new Letter('o'), new Letter('m')))); 'm'))));
words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter(
new Letter('u'), new Letter('r')))); 'r'))));
words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter(
new Letter('u'), new Letter('t'), new Letter('h')))); 't'), new Letter('h'))));
return new Sentence(words); return new Sentence(words);

View File

@ -24,5 +24,4 @@ public class Sentence extends LetterComposite {
protected void printThisAfter() { protected void printThisAfter() {
System.out.print("."); System.out.print(".");
} }
} }

View File

@ -24,5 +24,4 @@ public class Word extends LetterComposite {
protected void printThisAfter() { protected void printThisAfter() {
// nop // nop
} }
} }

View File

@ -7,14 +7,16 @@ import org.apache.log4j.Logger;
/** /**
* *
* Data Access Object (DAO) is an object that provides an abstract interface to some type of database or other * Data Access Object (DAO) is an object that provides an abstract interface to some type of
* persistence mechanism. By mapping application calls to the persistence layer, DAO provide some specific data * database or other persistence mechanism. By mapping application calls to the persistence layer,
* operations without exposing details of the database. This isolation supports the Single responsibility principle. * DAO provide some specific data operations without exposing details of the database. This
* It separates what data accesses the application needs, in terms of domain-specific objects and data types * isolation supports the Single responsibility principle. It separates what data accesses the
* (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS. * application needs, in terms of domain-specific objects and data types (the public interface of
* the DAO), from how these needs can be satisfied with a specific DBMS.
* <p> * <p>
* With the DAO pattern, we can use various method calls to retrieve/add/delete/update data without directly * With the DAO pattern, we can use various method calls to retrieve/add/delete/update data without
* interacting with the data. The below example demonstrates basic CRUD operations: select, add, update, and delete. * directly interacting with the data. The below example demonstrates basic CRUD operations: select,
* add, update, and delete.
* *
*/ */
public class App { public class App {

View File

@ -2,21 +2,21 @@ package com.iluwatar.decorator;
/** /**
* *
* The Decorator pattern is a more flexible alternative to subclassing. The Decorator * The Decorator pattern is a more flexible alternative to subclassing. The Decorator class
* class implements the same interface as the target and uses composition to * implements the same interface as the target and uses composition to "decorate" calls to the
* "decorate" calls to the target. Using the Decorator pattern it is possible to * target. Using the Decorator pattern it is possible to change the behavior of the class during
* change the behavior of the class during runtime. * runtime.
* <p> * <p>
* In this example we show how the simple {@link Troll} first attacks and then * In this example we show how the simple {@link Troll} first attacks and then flees the battle.
* flees the battle. Then we decorate the {@link Troll} with a {@link SmartTroll} * Then we decorate the {@link Troll} with a {@link SmartTroll} and perform the attack again. You
* and perform the attack again. You can see how the behavior changes after the * can see how the behavior changes after the decoration.
* decoration.
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -1,10 +1,9 @@
package com.iluwatar.decorator; package com.iluwatar.decorator;
/** /**
* SmartTroll is a decorator for {@link Hostile} objects. * SmartTroll is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface
* The calls to the {@link Hostile} interface are intercepted * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile}
* and decorated. Finally the calls are delegated * object.
* to the decorated {@link Hostile} object.
* *
*/ */
public class SmartTroll implements Hostile { public class SmartTroll implements Hostile {
@ -32,5 +31,4 @@ public class SmartTroll implements Hostile {
System.out.println("The troll calls for help!"); System.out.println("The troll calls for help!");
decorated.fleeBattle(); decorated.fleeBattle();
} }
} }

View File

@ -19,5 +19,4 @@ public class Troll implements Hostile {
public void fleeBattle() { public void fleeBattle() {
System.out.println("The troll shrieks in horror and runs away!"); System.out.println("The troll shrieks in horror and runs away!");
} }
} }

View File

@ -2,9 +2,8 @@ package com.iluwatar.dependency.injection;
/** /**
* *
* AdvancedWizard implements inversion of control. * AdvancedWizard implements inversion of control. It depends on abstraction that can be injected
* It depends on abstraction that can be injected through * through its constructor.
* its constructor.
* *
*/ */
public class AdvancedWizard implements Wizard { public class AdvancedWizard implements Wizard {

View File

@ -10,27 +10,28 @@ import com.google.inject.Injector;
* - High-level modules should not depend on low-level modules. Both should depend on abstractions. * - High-level modules should not depend on low-level modules. Both should depend on abstractions.
* - Abstractions should not depend on details. Details should depend on abstractions. * - Abstractions should not depend on details. Details should depend on abstractions.
* <p> * <p>
* In this example we show you three different wizards. The first one ({@link SimpleWizard}) is a naive * In this example we show you three different wizards. The first one ({@link SimpleWizard}) is a
* implementation violating the inversion of control principle. It depends directly on a concrete * naive implementation violating the inversion of control principle. It depends directly on a
* implementation which cannot be changed. * concrete implementation which cannot be changed.
* <p> * <p>
* The second wizard ({@link AdvancedWizard}) is more flexible. It does not depend on any concrete implementation * The second wizard ({@link AdvancedWizard}) is more flexible. It does not depend on any concrete
* but abstraction. It utilizes Dependency Injection pattern allowing its {@link Tobacco} dependency to be * implementation but abstraction. It utilizes Dependency Injection pattern allowing its
* injected through its constructor. This way, handling the dependency is no longer the wizard's * {@link Tobacco} dependency to be injected through its constructor. This way, handling the
* responsibility. It is resolved outside the wizard class. * dependency is no longer the wizard's responsibility. It is resolved outside the wizard class.
* <p> * <p>
* The third example takes the pattern a step further. It uses Guice framework for Dependency Injection. * The third example takes the pattern a step further. It uses Guice framework for Dependency
* {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then used to create * Injection. {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then
* {@link GuiceWizard} object with correct dependencies. * used to create {@link GuiceWizard} object with correct dependencies.
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
*/ */
public static void main( String[] args ) { public static void main(String[] args) {
SimpleWizard simpleWizard = new SimpleWizard(); SimpleWizard simpleWizard = new SimpleWizard();
simpleWizard.smoke(); simpleWizard.smoke();

View File

@ -4,9 +4,8 @@ import javax.inject.Inject;
/** /**
* *
* GuiceWizard implements inversion of control. * GuiceWizard implements inversion of control. Its dependencies are injected through its
* Its dependencies are injected through its constructor * constructor by Guice framework.
* by Guice framework.
* *
*/ */
public class GuiceWizard implements Wizard { public class GuiceWizard implements Wizard {

View File

@ -2,8 +2,8 @@ package com.iluwatar.dependency.injection;
/** /**
* *
* Naive Wizard implementation violating the inversion of control principle. * Naive Wizard implementation violating the inversion of control principle. It should depend on
* It should depend on abstraction instead. * abstraction instead.
* *
*/ */
public class SimpleWizard implements Wizard { public class SimpleWizard implements Wizard {

View File

@ -8,6 +8,7 @@ package com.iluwatar.dependency.injection;
public abstract class Tobacco { public abstract class Tobacco {
public void smoke(Wizard wizard) { public void smoke(Wizard wizard) {
System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this.getClass().getSimpleName())); System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this
.getClass().getSimpleName()));
} }
} }