Merge pull request #281 from ankurkaushal/master

Reformat according to google style guide
This commit is contained in:
Ilkka Seppälä 2015-11-02 21:39:17 +02:00
commit fe63c9cec4
438 changed files with 8257 additions and 8382 deletions

View File

@ -3,21 +3,18 @@ package com.iluwatar.abstractfactory;
/** /**
* *
* The Abstract Factory pattern provides a way to encapsulate a group of individual * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that
* factories that have a common theme without specifying their concrete classes. In * have a common theme without specifying their concrete classes. In normal usage, the client
* normal usage, the client software creates a concrete implementation of the abstract * software creates a concrete implementation of the abstract factory and then uses the generic
* factory and then uses the generic interface of the factory to create the concrete * interface of the factory to create the concrete objects that are part of the theme. The client
* objects that are part of the theme. The client does not know (or care) which * does not know (or care) which concrete objects it gets from each of these internal factories,
* concrete objects it gets from each of these internal factories, since it uses only * since it uses only the generic interfaces of their products. This pattern separates the details
* the generic interfaces of their products. This pattern separates the details of * of implementation of a set of objects from their general usage and relies on object composition,
* implementation of a set of objects from their general usage and relies on object * as object creation is implemented in methods exposed in the factory interface.
* composition, as object creation is implemented in methods exposed in the factory
* interface.
* <p> * <p>
* The essence of the Abstract Factory pattern is a factory interface * The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) and
* ({@link KingdomFactory}) and its implementations ({@link ElfKingdomFactory}, * its implementations ({@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses both
* {@link OrcKingdomFactory}). The example uses both concrete implementations to * concrete implementations to create a king, a castle and an army.
* create a king, a castle and an army.
* *
*/ */
public class App { public class App {
@ -28,6 +25,7 @@ public class App {
/** /**
* Creates kingdom * Creates kingdom
*
* @param factory * @param factory
*/ */
public void createKingdom(final KingdomFactory factory) { public void createKingdom(final KingdomFactory factory) {

View File

@ -18,5 +18,4 @@ public class OrcKingdomFactory implements KingdomFactory {
public Army createArmy() { public Army createArmy() {
return new OrcArmy(); return new OrcArmy();
} }
} }

View File

@ -1,4 +1,5 @@
package com.iluwatar.abstractfactory; package com.iluwatar.abstractfactory;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;

View File

@ -2,26 +2,25 @@ package com.iluwatar.adapter;
/** /**
* *
* An adapter helps two incompatible interfaces to work together. This is the real * An adapter helps two incompatible interfaces to work together. This is the real world definition
* world definition for an adapter. Interfaces may be incompatible but the inner * for an adapter. Interfaces may be incompatible but the inner functionality should suit the need.
* functionality should suit the need. The Adapter design pattern allows otherwise * The Adapter design pattern allows otherwise incompatible classes to work together by converting
* incompatible classes to work together by converting the interface of one class * the interface of one class into an interface expected by the clients.
* into an interface expected by the clients.
* <p> * <p>
* There are two variations of the Adapter pattern: The class adapter implements * There are two variations of the Adapter pattern: The class adapter implements the adaptee's
* the adaptee's interface whereas the object adapter uses composition to * interface whereas the object adapter uses composition to contain the adaptee in the adapter
* contain the adaptee in the adapter object. This example uses the object * object. This example uses the object adapter approach.
* adapter approach.
* <p> * <p>
* The Adapter ({@link GnomeEngineer}) converts the interface of the target class * The Adapter ({@link GnomeEngineer}) converts the interface of the target class (
* ({@link GoblinGlider}) into a suitable one expected by the client * {@link GoblinGlider}) into a suitable one expected by the client ({@link GnomeEngineeringManager}
* ({@link GnomeEngineeringManager}). * ).
* *
*/ */
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

@ -8,5 +8,4 @@ package com.iluwatar.adapter;
public interface Engineer { public interface Engineer {
void operateDevice(); void operateDevice();
} }

View File

@ -2,8 +2,8 @@ package com.iluwatar.adapter;
/** /**
* *
* Adapter class. Adapts the interface of the device ({@link GoblinGlider}) into * Adapter class. Adapts the interface of the device ({@link GoblinGlider}) into {@link Engineer}
* {@link Engineer} interface expected by the client ({@link GnomeEngineeringManager}). * interface expected by the client ({@link GnomeEngineeringManager}).
* *
*/ */
public class GnomeEngineer implements Engineer { public class GnomeEngineer implements Engineer {
@ -20,5 +20,4 @@ public class GnomeEngineer implements Engineer {
glider.gainSpeed(); glider.gainSpeed();
glider.takeOff(); glider.takeOff();
} }
} }

View File

@ -4,23 +4,24 @@ import java.util.concurrent.Callable;
/** /**
* This application demonstrates the async method invocation pattern. Key parts of the pattern are * This application demonstrates the async method invocation pattern. Key parts of the pattern are
* <code>AsyncResult</code> which is an intermediate container for an asynchronously evaluated value, * <code>AsyncResult</code> which is an intermediate container for an asynchronously evaluated
* <code>AsyncCallback</code> which can be provided to be executed on task completion and * value, <code>AsyncCallback</code> which can be provided to be executed on task completion and
* <code>AsyncExecutor</code> that manages the execution of the async tasks. * <code>AsyncExecutor</code> that manages the execution of the async tasks.
* <p> * <p>
* The main method shows example flow of async invocations. The main thread starts multiple tasks with * The main method shows example flow of async invocations. The main thread starts multiple tasks
* variable durations and then continues its own work. When the main thread has done it's job it collects * with variable durations and then continues its own work. When the main thread has done it's job
* the results of the async tasks. Two of the tasks are handled with callbacks, meaning the callbacks are * it collects the results of the async tasks. Two of the tasks are handled with callbacks, meaning
* executed immediately when the tasks complete. * the callbacks are executed immediately when the tasks complete.
* <p> * <p>
* Noteworthy difference of thread usage between the async results and callbacks is that the async results * Noteworthy difference of thread usage between the async results and callbacks is that the async
* are collected in the main thread but the callbacks are executed within the worker threads. This should be * results are collected in the main thread but the callbacks are executed within the worker
* noted when working with thread pools. * threads. This should be noted when working with thread pools.
* <p> * <p>
* Java provides its own implementations of async method invocation pattern. FutureTask, CompletableFuture * Java provides its own implementations of async method invocation pattern. FutureTask,
* and ExecutorService are the real world implementations of this pattern. But due to the nature of parallel * CompletableFuture and ExecutorService are the real world implementations of this pattern. But due
* programming, the implementations are not trivial. This example does not take all possible scenarios into * to the nature of parallel programming, the implementations are not trivial. This example does not
* account but rather provides a simple version that helps to understand the pattern. * take all possible scenarios into account but rather provides a simple version that helps to
* understand the pattern.
* *
* @see AsyncResult * @see AsyncResult
* @see AsyncCallback * @see AsyncCallback
@ -40,8 +41,10 @@ public class App {
AsyncResult<Integer> asyncResult1 = executor.startProcess(lazyval(10, 500)); AsyncResult<Integer> asyncResult1 = executor.startProcess(lazyval(10, 500));
AsyncResult<String> asyncResult2 = executor.startProcess(lazyval("test", 300)); AsyncResult<String> asyncResult2 = executor.startProcess(lazyval("test", 300));
AsyncResult<Long> asyncResult3 = executor.startProcess(lazyval(50L, 700)); AsyncResult<Long> asyncResult3 = executor.startProcess(lazyval(50L, 700));
AsyncResult<Integer> asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4")); AsyncResult<Integer> asyncResult4 =
AsyncResult<String> asyncResult5 = executor.startProcess(lazyval("callback", 600), callback("Callback result 5")); executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
AsyncResult<String> asyncResult5 =
executor.startProcess(lazyval("callback", 600), callback("Callback result 5"));
// emulate processing in the current thread while async tasks are running in their own threads // emulate processing in the current thread while async tasks are running in their own threads
Thread.sleep(350); // Oh boy I'm working hard here Thread.sleep(350); // Oh boy I'm working hard here

View File

@ -18,5 +18,4 @@ public interface AsyncCallback<T> {
* @param ex empty value if execution succeeds, some exception if executions fails * @param ex empty value if execution succeeds, some exception if executions fails
*/ */
void onComplete(T value, Optional<Exception> ex); void onComplete(T value, Optional<Exception> ex);
} }

View File

@ -38,5 +38,4 @@ public interface AsyncExecutor {
* @throws InterruptedException if the execution is interrupted * @throws InterruptedException if the execution is interrupted
*/ */
<T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException; <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
} }

View File

@ -34,7 +34,8 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
} }
@Override @Override
public <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException { public <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException,
InterruptedException {
if (asyncResult.isCompleted()) { if (asyncResult.isCompleted()) {
return asyncResult.getValue(); return asyncResult.getValue();
} else { } else {
@ -44,8 +45,8 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
} }
/** /**
* Simple implementation of async result that allows completing it successfully with a value * Simple implementation of async result that allows completing it successfully with a value or
* or exceptionally with an exception. A really simplified version from its real life cousins * exceptionally with an exception. A really simplified version from its real life cousins
* FutureTask and CompletableFuture. * FutureTask and CompletableFuture.
* *
* @see java.util.concurrent.FutureTask * @see java.util.concurrent.FutureTask
@ -70,8 +71,8 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
} }
/** /**
* Sets the value from successful execution and executes callback if available. Notifies * Sets the value from successful execution and executes callback if available. Notifies any
* any thread waiting for completion. * thread waiting for completion.
* *
* @param value value of the evaluated task * @param value value of the evaluated task
*/ */
@ -85,8 +86,8 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
} }
/** /**
* Sets the exception from failed execution and executes callback if available. Notifies * Sets the exception from failed execution and executes callback if available. Notifies any
* any thread waiting for completion. * thread waiting for completion.
* *
* @param exception exception of the failed task * @param exception exception of the failed task
*/ */

View File

@ -14,5 +14,4 @@ public class AppTest {
String[] args = {}; String[] args = {};
App.main(args); App.main(args);
} }
} }

View File

@ -2,41 +2,38 @@ package com.iluwatar.bridge;
/** /**
* *
* The Bridge pattern can also be thought of as two layers of abstraction. With Bridge, * The Bridge pattern can also be thought of as two layers of abstraction. With Bridge, you can
* you can decouple an abstraction from its implementation so that the two can vary independently. * decouple an abstraction from its implementation so that the two can vary independently.
* <p> * <p>
* In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation * In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation (
* ({@link MagicWeaponImpl}) have their own class hierarchies. The interface of the * {@link MagicWeaponImpl}) have their own class hierarchies. The interface of the implementations
* implementations can be changed without affecting the clients. * can be changed without affecting the clients.
* *
*/ */
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) {
BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon( BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur());
new Excalibur());
blindingMagicWeapon.wield(); blindingMagicWeapon.wield();
blindingMagicWeapon.blind(); blindingMagicWeapon.blind();
blindingMagicWeapon.swing(); blindingMagicWeapon.swing();
blindingMagicWeapon.unwield(); blindingMagicWeapon.unwield();
FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon( FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir());
new Mjollnir());
flyingMagicWeapon.wield(); flyingMagicWeapon.wield();
flyingMagicWeapon.fly(); flyingMagicWeapon.fly();
flyingMagicWeapon.swing(); flyingMagicWeapon.swing();
flyingMagicWeapon.unwield(); flyingMagicWeapon.unwield();
SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon( SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer());
new Stormbringer());
soulEatingMagicWeapon.wield(); soulEatingMagicWeapon.wield();
soulEatingMagicWeapon.swing(); soulEatingMagicWeapon.swing();
soulEatingMagicWeapon.eatSoul(); soulEatingMagicWeapon.eatSoul();
soulEatingMagicWeapon.unwield(); soulEatingMagicWeapon.unwield();
} }
} }

View File

@ -34,5 +34,4 @@ public class BlindingMagicWeapon extends MagicWeapon {
public void blind() { public void blind() {
getImp().blindImp(); getImp().blindImp();
} }
} }

View File

@ -24,8 +24,6 @@ public class Excalibur extends BlindingMagicWeaponImpl {
@Override @Override
public void blindImp() { public void blindImp() {
System.out System.out.println("bright light streams from Excalibur blinding the enemy");
.println("bright light streams from Excalibur blinding the enemy");
} }
} }

View File

@ -22,5 +22,4 @@ public abstract class MagicWeapon {
public MagicWeaponImpl getImp() { public MagicWeaponImpl getImp() {
return imp; return imp;
} }
} }

View File

@ -24,8 +24,6 @@ public class Mjollnir extends FlyingMagicWeaponImpl {
@Override @Override
public void flyImp() { public void flyImp() {
System.out System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
} }
} }

View File

@ -26,5 +26,4 @@ public class Stormbringer extends SoulEatingMagicWeaponImpl {
public void eatSoulImp() { public void eatSoulImp() {
System.out.println("Stormbringer devours the enemy's soul"); System.out.println("Stormbringer devours the enemy's soul");
} }
} }

View File

@ -4,51 +4,51 @@ import com.iluwatar. builder.Hero.HeroBuilder;
/** /**
* *
* The intention of the Builder pattern is to find a solution to the telescoping * The intention of the Builder pattern is to find a solution to the telescoping constructor
* constructor anti-pattern. The telescoping constructor anti-pattern occurs when the * anti-pattern. The telescoping constructor anti-pattern occurs when the increase of object
* increase of object constructor parameter combination leads to an exponential list * constructor parameter combination leads to an exponential list of constructors. Instead of using
* of constructors. Instead of using numerous constructors, the builder pattern uses * numerous constructors, the builder pattern uses another object, a builder, that receives each
* another object, a builder, that receives each initialization parameter step by step * initialization parameter step by step and then returns the resulting constructed object at once.
* and then returns the resulting constructed object at once.
* <p> * <p>
* The Builder pattern has another benefit. It can be used for objects that contain * The Builder pattern has another benefit. It can be used for objects that contain flat data (html
* flat data (html code, SQL query, X.509 certificate...), that is to say, data that * code, SQL query, X.509 certificate...), that is to say, data that can't be easily edited. This
* can't be easily edited. This type of data cannot be edited step by step and must * type of data cannot be edited step by step and must be edited at once. The best way to construct
* be edited at once. The best way to construct such an object is to use a builder * such an object is to use a builder class.
* class.
* <p> * <p>
* In this example we have the Builder pattern variation as described by Joshua Bloch in * In this example we have the Builder pattern variation as described by Joshua Bloch in Effective
* Effective Java 2nd Edition. * Java 2nd Edition.
* <p> * <p>
* We want to build {@link Hero} objects, but its construction is complex because of the * We want to build {@link Hero} objects, but its construction is complex because of the many
* many parameters needed. To aid the user we introduce {@link HeroBuilder} class. * parameters needed. To aid the user we introduce {@link HeroBuilder} class. {@link HeroBuilder}
* {@link HeroBuilder} takes the minimum parameters to build {@link Hero} object in its * takes the minimum parameters to build {@link Hero} object in its constructor. After that
* constructor. After that additional configuration for the {@link Hero} object can be * additional configuration for the {@link Hero} object can be done using the fluent
* done using the fluent {@link HeroBuilder} interface. When configuration is ready the * {@link HeroBuilder} interface. When configuration is ready the build method is called to receive
* build method is called to receive the final {@link Hero} object. * the final {@link Hero} object.
* *
*/ */
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) {
Hero mage = new HeroBuilder(Profession.MAGE, "Riobard") Hero mage =
.withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER) new HeroBuilder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK)
.build(); .withWeapon(Weapon.DAGGER).build();
System.out.println(mage); System.out.println(mage);
Hero warrior = new HeroBuilder(Profession.WARRIOR, "Amberjill") Hero warrior =
.withHairColor(HairColor.BLOND) new HeroBuilder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
.withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL) .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
.withWeapon(Weapon.SWORD).build(); .build();
System.out.println(warrior); System.out.println(warrior);
Hero thief = new HeroBuilder(Profession.THIEF, "Desmond") Hero thief =
.withHairType(HairType.BALD).withWeapon(Weapon.BOW).build(); new HeroBuilder(Profession.THIEF, "Desmond").withHairType(HairType.BALD)
.withWeapon(Weapon.BOW).build();
System.out.println(thief); System.out.println(thief);
} }

View File

@ -7,7 +7,8 @@ package com.iluwatar.builder;
*/ */
public enum HairType { public enum HairType {
BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY("long curly"); BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY(
"long curly");
private String title; private String title;

View File

@ -95,8 +95,7 @@ public class Hero {
public HeroBuilder(Profession profession, String name) { public HeroBuilder(Profession profession, String name) {
if (profession == null || name == null) { if (profession == null || name == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException("profession and name can not be null");
"profession and name can not be null");
} }
this.profession = profession; this.profession = profession;
this.name = name; this.name = name;

View File

@ -13,5 +13,4 @@ public enum Profession {
public String toString() { public String toString() {
return name().toLowerCase(); return name().toLowerCase();
} }
} }

View File

@ -13,5 +13,4 @@ public enum Weapon {
public String toString() { public String toString() {
return name().toLowerCase(); return name().toLowerCase();
} }
} }

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,24 +10,25 @@ 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) {

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()));
} }
} }

View File

@ -6,21 +6,21 @@ import java.util.concurrent.TimeUnit;
/** /**
* *
* Double Checked Locking is a concurrency design pattern used to reduce the overhead * Double Checked Locking is a concurrency design pattern used to reduce the overhead of acquiring a
* of acquiring a lock by first testing the locking criterion (the "lock hint") without * lock by first testing the locking criterion (the "lock hint") without actually acquiring the
* actually acquiring the lock. Only if the locking criterion check indicates that * lock. Only if the locking criterion check indicates that locking is required does the actual
* locking is required does the actual locking logic proceed. * locking logic proceed.
* <p> * <p>
* In {@link Inventory} we store the items with a given size. However, we do not store * In {@link Inventory} we store the items with a given size. However, we do not store more items
* more items than the inventory size. To address concurrent access problems we * than the inventory size. To address concurrent access problems we use double checked locking to
* use double checked locking to add item to inventory. In this method, the * add item to inventory. In this method, the thread which gets the lock first adds the item.
* thread which gets the lock first adds the item.
* *
*/ */
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) {
@ -28,8 +28,7 @@ public class App {
ExecutorService executorService = Executors.newFixedThreadPool(3); ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
executorService.execute(() -> { executorService.execute(() -> {
while (inventory.addItem(new Item())) while (inventory.addItem(new Item()));
;
}); });
} }

View File

@ -28,8 +28,7 @@ public class Inventory {
try { try {
if (items.size() < inventorySize) { if (items.size() < inventorySize) {
items.add(item); items.add(item);
System.out.println(Thread.currentThread() System.out.println(Thread.currentThread() + ": items.size()=" + items.size()
+ ": items.size()=" + items.size()
+ ", inventorySize=" + inventorySize); + ", inventorySize=" + inventorySize);
return true; return true;
} }
@ -39,5 +38,4 @@ public class Inventory {
} }
return false; return false;
} }
} }

View File

@ -6,20 +6,20 @@ import java.util.List;
/** /**
* *
* When a message with a parameter is sent to an object, the resultant behaviour is defined by the * When a message with a parameter is sent to an object, the resultant behaviour is defined by the
* implementation of that method in the receiver. Sometimes the behaviour must also be determined * implementation of that method in the receiver. Sometimes the behaviour must also be determined by
* by the type of the parameter. * the type of the parameter.
* <p> * <p>
* One way to implement this would be to create multiple instanceof-checks for the methods parameter. * One way to implement this would be to create multiple instanceof-checks for the methods
* However, this creates a maintenance issue. When new types are added we would also need to change * parameter. However, this creates a maintenance issue. When new types are added we would also need
* the method's implementation and add a new instanceof-check. This violates the single responsibility * to change the method's implementation and add a new instanceof-check. This violates the single
* principle - a class should have only one reason to change. * responsibility principle - a class should have only one reason to change.
* <p> * <p>
* Instead of the instanceof-checks a better way is to make another virtual call on the parameter * Instead of the instanceof-checks a better way is to make another virtual call on the parameter
* object. This way new functionality can be easily added without the need to modify existing * object. This way new functionality can be easily added without the need to modify existing
* implementation (open-closed principle). * implementation (open-closed principle).
* <p> * <p>
* In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other.
* object has its own coordinates which are checked against the other objects' coordinates. If * Each object has its own coordinates which are checked against the other objects' coordinates. If
* there is an overlap, then the objects collide utilizing the Double Dispatch pattern. * there is an overlap, then the objects collide utilizing the Double Dispatch pattern.
* *
*/ */
@ -27,6 +27,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) {
@ -40,7 +41,10 @@ public class App {
System.out.println(""); System.out.println("");
// collision check // collision check
objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { if (o1 != o2 && o1.intersectsWith(o2)) o1.collision(o2); } )); objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> {
if (o1 != o2 && o1.intersectsWith(o2))
o1.collision(o2);
}));
System.out.println(""); System.out.println("");
// output eventual object statuses // output eventual object statuses

View File

@ -2,8 +2,7 @@ package com.iluwatar.doubledispatch;
/** /**
* *
* Game objects have coordinates and some * Game objects have coordinates and some other status information.
* other status information.
* *
*/ */
public abstract class GameObject extends Rectangle { public abstract class GameObject extends Rectangle {

View File

@ -18,21 +18,25 @@ public class Meteoroid extends GameObject {
@Override @Override
public void collisionResolve(FlamingAsteroid asteroid) { public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName())); System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this
.getClass().getSimpleName()));
} }
@Override @Override
public void collisionResolve(Meteoroid meteoroid) { public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName())); System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this
.getClass().getSimpleName()));
} }
@Override @Override
public void collisionResolve(SpaceStationMir mir) { public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass().getSimpleName())); System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass()
.getSimpleName()));
} }
@Override @Override
public void collisionResolve(SpaceStationIss iss) { public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass().getSimpleName())); System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass()
.getSimpleName()));
} }
} }

View File

@ -2,8 +2,7 @@ package com.iluwatar.doubledispatch;
/** /**
* *
* Rectangle has coordinates and can be checked for overlap against * Rectangle has coordinates and can be checked for overlap against other Rectangles.
* other Rectangles.
* *
*/ */
public class Rectangle { public class Rectangle {
@ -23,18 +22,22 @@ public class Rectangle {
public int getLeft() { public int getLeft() {
return left; return left;
} }
public int getTop() { public int getTop() {
return top; return top;
} }
public int getRight() { public int getRight() {
return right; return right;
} }
public int getBottom() { public int getBottom() {
return bottom; return bottom;
} }
boolean intersectsWith(Rectangle r) { boolean intersectsWith(Rectangle r) {
return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r.getBottom() < getTop()); return !(r.getLeft() > getRight() || r.getRight() < getLeft() || r.getTop() > getBottom() || r
.getBottom() < getTop());
} }
@Override @Override

View File

@ -18,34 +18,31 @@ public class SpaceStationMir extends GameObject {
@Override @Override
public void collisionResolve(FlamingAsteroid asteroid) { public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid
asteroid.getClass().getSimpleName(), this.getClass().getSimpleName(), .getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass()
this.getClass().getSimpleName(), this.getClass().getSimpleName())); .getSimpleName(), this.getClass().getSimpleName()));
setDamaged(true); setDamaged(true);
setOnFire(true); setOnFire(true);
} }
@Override @Override
public void collisionResolve(Meteoroid meteoroid) { public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s. %s is damaged!", System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass()
meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName(), .getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
this.getClass().getSimpleName()));
setDamaged(true); setDamaged(true);
} }
@Override @Override
public void collisionResolve(SpaceStationMir mir) { public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s. %s is damaged!", System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(),
mir.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
this.getClass().getSimpleName()));
setDamaged(true); setDamaged(true);
} }
@Override @Override
public void collisionResolve(SpaceStationIss iss) { public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s. %s is damaged!", System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(),
iss.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
this.getClass().getSimpleName()));
setDamaged(true); setDamaged(true);
} }
} }

View File

@ -5,22 +5,23 @@ import java.util.List;
/** /**
* *
* A system with lots of objects can lead to complexities when a client wants to subscribe * A system with lots of objects can lead to complexities when a client wants to subscribe to
* to events. The client has to find and register for each object individually, if each * events. The client has to find and register for each object individually, if each object has
* object has multiple events then each event requires a separate subscription. * multiple events then each event requires a separate subscription.
* <p> * <p>
* An Event Aggregator acts as a single source of events for many objects. It registers * An Event Aggregator acts as a single source of events for many objects. It registers for all the
* for all the events of the many objects allowing clients to register with just the aggregator. * events of the many objects allowing clients to register with just the aggregator.
* <p> * <p>
* In the example {@link LordBaelish}, {@link LordVarys} and {@link Scout} deliver events to * In the example {@link LordBaelish}, {@link LordVarys} and {@link Scout} deliver events to
* {@link KingsHand}. {@link KingsHand}, the event aggregator, then delivers the events * {@link KingsHand}. {@link KingsHand}, the event aggregator, then delivers the events to
* to {@link KingJoffrey}. * {@link KingJoffrey}.
* *
*/ */
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

@ -7,7 +7,8 @@ package com.iluwatar.event.aggregator;
*/ */
public enum Event { public enum Event {
STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED("Traitor detected"); STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED(
"Traitor detected");
private String description; private String description;

View File

@ -2,8 +2,7 @@ package com.iluwatar.event.aggregator;
/** /**
* *
* KingsHand observes events from multiple sources and delivers them * KingsHand observes events from multiple sources and delivers them to listeners.
* to listeners.
* *
*/ */
public class KingsHand extends EventEmitter implements EventObserver { public class KingsHand extends EventEmitter implements EventObserver {

View File

@ -7,7 +7,8 @@ package com.iluwatar.event.aggregator;
*/ */
public enum Weekday { public enum Weekday {
MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY("Saturday"), SUNDAY("Sunday"); MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY(
"Friday"), SATURDAY("Saturday"), SUNDAY("Sunday");
private String description; private String description;

View File

@ -1,4 +1,5 @@
package com.iluwatar.event.aggregator; package com.iluwatar.event.aggregator;
import org.junit.Test; import org.junit.Test;
import com.iluwatar.event.aggregator.App; import com.iluwatar.event.aggregator.App;

View File

@ -4,19 +4,20 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
/** /**
* The Execute Around idiom specifies some code to be executed before and after * The Execute Around idiom specifies some code to be executed before and after a method. Typically
* a method. Typically the idiom is used when the API has methods to be executed in * the idiom is used when the API has methods to be executed in pairs, such as resource
* pairs, such as resource allocation/deallocation or lock acquisition/release. * allocation/deallocation or lock acquisition/release.
* <p> * <p>
* In this example, we have {@link SimpleFileWriter} class that opens and closes the file * In this example, we have {@link SimpleFileWriter} class that opens and closes the file for the
* for the user. The user specifies only what to do with the file by providing the * user. The user specifies only what to do with the file by providing the {@link FileWriterAction}
* {@link FileWriterAction} implementation. * implementation.
* *
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point
*
* @param args command line args * @param args command line args
* @throws IOException * @throws IOException
*/ */

View File

@ -5,9 +5,8 @@ import java.io.IOException;
/** /**
* *
* SimpleFileWriter handles opening and closing file for the user. The user * SimpleFileWriter handles opening and closing file for the user. The user only has to specify what
* only has to specify what to do with the file resource through {@link FileWriterAction} * to do with the file resource through {@link FileWriterAction} parameter.
* parameter.
* *
*/ */
public class SimpleFileWriter { public class SimpleFileWriter {

View File

@ -2,21 +2,22 @@ package com.iluwatar.facade;
/** /**
* *
* The Facade design pattern is often used when a system is very complex or difficult * The Facade design pattern is often used when a system is very complex or difficult to understand
* to understand because the system has a large number of interdependent classes or * because the system has a large number of interdependent classes or its source code is
* its source code is unavailable. This pattern hides the complexities of the larger * unavailable. This pattern hides the complexities of the larger system and provides a simpler
* system and provides a simpler interface to the client. It typically involves a single * interface to the client. It typically involves a single wrapper class which contains a set of
* wrapper class which contains a set of members required by client. These members access * members required by client. These members access the system on behalf of the facade client and
* the system on behalf of the facade client and hide the implementation details. * hide the implementation details.
* <p> * <p>
* In this example the Facade is ({@link DwarvenGoldmineFacade}) and it provides a simpler * In this example the Facade is ({@link DwarvenGoldmineFacade}) and it provides a simpler interface
* interface to the goldmine subsystem. * to the goldmine subsystem.
* *
*/ */
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

@ -16,5 +16,4 @@ public class DwarvenCartOperator extends DwarvenMineWorker {
public String name() { public String name() {
return "Dwarf cart operator"; return "Dwarf cart operator";
} }
} }

View File

@ -16,5 +16,4 @@ public class DwarvenGoldDigger extends DwarvenMineWorker {
public String name() { public String name() {
return "Dwarf gold digger"; return "Dwarf gold digger";
} }
} }

View File

@ -6,12 +6,10 @@ import java.util.List;
/** /**
* *
* DwarvenGoldmineFacade provides a single interface * DwarvenGoldmineFacade provides a single interface through which users can operate the subsystems.
* through which users can operate the subsystems.
* *
* This makes the goldmine easier to operate and * This makes the goldmine easier to operate and cuts the dependencies from the goldmine user to the
* cuts the dependencies from the goldmine user to * subsystems.
* the subsystems.
* *
*/ */
public class DwarvenGoldmineFacade { public class DwarvenGoldmineFacade {
@ -37,7 +35,8 @@ public class DwarvenGoldmineFacade {
makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP); makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP);
} }
private void makeActions(Collection<DwarvenMineWorker> workers, DwarvenMineWorker.Action... actions) { private void makeActions(Collection<DwarvenMineWorker> workers,
DwarvenMineWorker.Action... actions) {
for (DwarvenMineWorker worker : workers) { for (DwarvenMineWorker worker : workers) {
worker.action(actions); worker.action(actions);
} }

View File

@ -16,5 +16,4 @@ public class DwarvenTunnelDigger extends DwarvenMineWorker {
public String name() { public String name() {
return "Dwarven tunnel digger"; return "Dwarven tunnel digger";
} }
} }

View File

@ -2,23 +2,23 @@ package com.iluwatar.factory.method;
/** /**
* *
* The Factory Method is a creational design pattern which uses factory methods to deal * The Factory Method is a creational design pattern which uses factory methods to deal with the
* with the problem of creating objects without specifying the exact class of object * problem of creating objects without specifying the exact class of object that will be created.
* that will be created. This is done by creating objects via calling a factory * This is done by creating objects via calling a factory method either specified in an interface
* method either specified in an interface and implemented by child classes, or implemented * and implemented by child classes, or implemented in a base class and optionally overridden by
* in a base class and optionally overridden by derived classesrather than by calling a * derived classesrather than by calling a constructor.
* constructor.
* <p> * <p>
* In this Factory Method example we have an interface ({@link Blacksmith}) with a method for * In this Factory Method example we have an interface ({@link Blacksmith}) with a method for
* creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses * creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses (
* ({@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce * {@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce objects of
* objects of their liking. * their liking.
* *
*/ */
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

@ -17,5 +17,4 @@ public class ElfWeapon implements Weapon {
public String toString() { public String toString() {
return "Elven " + weaponType; return "Elven " + weaponType;
} }
} }

View File

@ -10,5 +10,4 @@ public class OrcBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) { public Weapon manufactureWeapon(WeaponType weaponType) {
return new OrcWeapon(weaponType); return new OrcWeapon(weaponType);
} }
} }

View File

@ -17,5 +17,4 @@ public class OrcWeapon implements Weapon {
public String toString() { public String toString() {
return "Orcish " + weaponType; return "Orcish " + weaponType;
} }
} }

View File

@ -11,13 +11,15 @@ import java.util.function.Predicate;
import static java.lang.String.valueOf; import static java.lang.String.valueOf;
/** /**
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those * The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API.
* interfaces tend to mimic domain specific languages, so they can nearly be read as human languages. * Those interfaces tend to mimic domain specific languages, so they can nearly be read as human
* languages.
* <p> * <p>
* In this example two implementations of a {@link FluentIterable} interface are given. The * In this example two implementations of a {@link FluentIterable} interface are given. The
* {@link SimpleFluentIterable} evaluates eagerly and would be too costly for real world applications. * {@link SimpleFluentIterable} evaluates eagerly and would be too costly for real world
* The {@link LazyFluentIterable} is evaluated on termination. Their usage is demonstrated with a * applications. The {@link LazyFluentIterable} is evaluated on termination. Their usage is
* simple number list that is filtered, transformed and collected. The result is printed afterwards. * demonstrated with a simple number list that is filtered, transformed and collected. The result is
* printed afterwards.
* *
*/ */
public class App { public class App {
@ -25,10 +27,8 @@ public class App {
public static void main(String[] args) { public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>(); List<Integer> integerList = new ArrayList<>();
integerList.addAll(Arrays.asList( integerList.addAll(Arrays.asList(1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2,
1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, -68, 45));
45, 23, 2, -68, 45
));
prettyPrint("The initial list contains: ", integerList); prettyPrint("The initial list contains: ", integerList);

View File

@ -7,7 +7,8 @@ package com.iluwatar.flux.action;
*/ */
public enum Content { public enum Content {
PRODUCTS("Products - This page lists the company's products."), COMPANY("Company - This page displays information about the company."); PRODUCTS("Products - This page lists the company's products."), COMPANY(
"Company - This page displays information about the company.");
private String title; private String title;

View File

@ -11,13 +11,14 @@ import com.iluwatar.flux.view.MenuView;
* *
* Flux is the application architecture that Facebook uses for building client-side web * Flux is the application architecture that Facebook uses for building client-side web
* applications. Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with * applications. Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with
* a React view, the view propagates an action through a central dispatcher, to the various stores that * a React view, the view propagates an action through a central dispatcher, to the various stores
* hold the application's data and business logic, which updates all of the views that are affected. * that hold the application's data and business logic, which updates all of the views that are
* affected.
* <p> * <p>
* This example has two views: menu and content. They represent typical main menu and content area of * This example has two views: menu and content. They represent typical main menu and content area
* a web page. When menu item is clicked it triggers events through the dispatcher. The events are * of a web page. When menu item is clicked it triggers events through the dispatcher. The events
* received and handled by the stores updating their data as needed. The stores then notify the views * are received and handled by the stores updating their data as needed. The stores then notify the
* that they should rerender themselves. * views that they should rerender themselves.
* <p> * <p>
* http://facebook.github.io/flux/docs/overview.html * http://facebook.github.io/flux/docs/overview.html
* *
@ -26,6 +27,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

@ -21,8 +21,7 @@ public class Dispatcher {
private List<Store> stores = new LinkedList<>(); private List<Store> stores = new LinkedList<>();
private Dispatcher() { private Dispatcher() {}
}
public static Dispatcher getInstance() { public static Dispatcher getInstance() {
return instance; return instance;

View File

@ -5,8 +5,7 @@ import java.util.List;
/** /**
* *
* AlchemistShop holds potions on its shelves. * AlchemistShop holds potions on its shelves. It uses PotionFactory to provide the potions.
* It uses PotionFactory to provide the potions.
* *
*/ */
public class AlchemistShop { public class AlchemistShop {

View File

@ -2,22 +2,23 @@ package com.iluwatar.flyweight;
/** /**
* *
* Flyweight pattern is useful when the program needs a huge amount of objects. * Flyweight pattern is useful when the program needs a huge amount of objects. It provides means to
* It provides means to decrease resource usage by sharing object instances. * decrease resource usage by sharing object instances.
* <p> * <p>
* In this example {@link AlchemistShop} has great amount of potions on its shelves. * In this example {@link AlchemistShop} has great amount of potions on its shelves. To fill the
* To fill the shelves {@link AlchemistShop} uses {@link PotionFactory} (which represents * shelves {@link AlchemistShop} uses {@link PotionFactory} (which represents the Flyweight in this
* the Flyweight in this example). Internally {@link PotionFactory} holds a map * example). Internally {@link PotionFactory} holds a map of the potions and lazily creates new ones
* of the potions and lazily creates new ones when requested. * when requested.
* <p> * <p>
* To enable safe sharing, between clients and threads, Flyweight objects must * To enable safe sharing, between clients and threads, Flyweight objects must be immutable.
* be immutable. Flyweight objects are by definition value objects. * Flyweight objects are by definition value objects.
* *
*/ */
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

@ -9,8 +9,6 @@ public class HealingPotion implements Potion {
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel healed. (Potion=" System.out.println("You feel healed. (Potion=" + System.identityHashCode(this) + ")");
+ System.identityHashCode(this) + ")");
} }
} }

View File

@ -9,8 +9,6 @@ public class HolyWaterPotion implements Potion {
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel blessed. (Potion=" System.out.println("You feel blessed. (Potion=" + System.identityHashCode(this) + ")");
+ System.identityHashCode(this) + ")");
} }
} }

View File

@ -9,8 +9,6 @@ public class InvisibilityPotion implements Potion {
@Override @Override
public void drink() { public void drink() {
System.out.println("You become invisible. (Potion=" System.out.println("You become invisible. (Potion=" + System.identityHashCode(this) + ")");
+ System.identityHashCode(this) + ")");
} }
} }

View File

@ -9,8 +9,6 @@ public class PoisonPotion implements Potion {
@Override @Override
public void drink() { public void drink() {
System.out.println("Urgh! This is poisonous. (Potion=" System.out.println("Urgh! This is poisonous. (Potion=" + System.identityHashCode(this) + ")");
+ System.identityHashCode(this) + ")");
} }
} }

View File

@ -5,10 +5,9 @@ import java.util.Map;
/** /**
* *
* PotionFactory is the Flyweight in this example. * PotionFactory is the Flyweight in this example. It minimizes memory use by sharing object
* It minimizes memory use by sharing object instances. * instances. It holds a map of potion instances and new potions are created only when none of the
* It holds a map of potion instances and new potions * type already exists.
* are created only when none of the type already exists.
* *
*/ */
public class PotionFactory { public class PotionFactory {

View File

@ -9,7 +9,6 @@ public class StrengthPotion implements Potion {
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel strong. (Potion=" System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")");
+ System.identityHashCode(this) + ")");
} }
} }

View File

@ -8,63 +8,62 @@ import java.util.concurrent.LinkedBlockingQueue;
* {@link AsyncTask} and {@link AsynchronousService}. * {@link AsyncTask} and {@link AsynchronousService}.
* *
* <p> * <p>
* <i>PROBLEM</i> * <i>PROBLEM</i> <br/>
* <br/> * A concurrent system have a mixture of short duration, mid duration and long duration tasks. Mid
* A concurrent system have a mixture of short duration, mid duration and long duration tasks. * or long duration tasks should be performed asynchronously to meet quality of service
* Mid or long duration tasks should be performed asynchronously to meet quality of service
* requirements. * requirements.
* *
* <p><i>INTENT</i> * <p>
* <br/> * <i>INTENT</i> <br/>
* The intent of this pattern is to separate the the synchronous and asynchronous processing * The intent of this pattern is to separate the the synchronous and asynchronous processing in the
* in the concurrent application by introducing two intercommunicating layers - one for sync * concurrent application by introducing two intercommunicating layers - one for sync and one for
* and one for async. This simplifies the programming without unduly affecting the performance. * async. This simplifies the programming without unduly affecting the performance.
* *
* <p> * <p>
* <i>APPLICABILITY</i> * <i>APPLICABILITY</i> <br/>
* <br/>
* <ul> * <ul>
* <li>UNIX network subsystems - In operating systems network operations are carried out * <li>UNIX network subsystems - In operating systems network operations are carried out
* asynchronously with help of hardware level interrupts.</li> * asynchronously with help of hardware level interrupts.</li>
* <li>CORBA - At the asynchronous layer one thread is associated with each socket that is * <li>CORBA - At the asynchronous layer one thread is associated with each socket that is connected
* connected to the client. Thread blocks waiting for CORBA requests from the client. On receiving * to the client. Thread blocks waiting for CORBA requests from the client. On receiving request it
* request it is inserted in the queuing layer which is then picked up by synchronous layer which * is inserted in the queuing layer which is then picked up by synchronous layer which processes the
* processes the request and sends response back to the client.</li> * request and sends response back to the client.</li>
* <li>Android AsyncTask framework - Framework provides a way to execute long running blocking calls, * <li>Android AsyncTask framework - Framework provides a way to execute long running blocking
* such as downloading a file, in background threads so that the UI thread remains free to respond * calls, such as downloading a file, in background threads so that the UI thread remains free to
* to user inputs.</i> * respond to user inputs.</i>
* </ul> * </ul>
* *
* <p> * <p>
* <i>IMPLEMENTATION</i> * <i>IMPLEMENTATION</i> <br/>
* <br/> * The main method creates an asynchronous service which does not block the main thread while the
* The main method creates an asynchronous service which does not block the main thread while * task is being performed. The main thread continues its work which is similar to Async Method
* the task is being performed. The main thread continues its work which is similar to Async Method * Invocation pattern. The difference between them is that there is a queuing layer between
* Invocation pattern. The difference between them is that there is a queuing layer between Asynchronous * Asynchronous layer and synchronous layer, which allows for different communication patterns
* layer and synchronous layer, which allows for different communication patterns between both layers. * between both layers. Such as Priority Queue can be used as queuing layer to prioritize the way
* Such as Priority Queue can be used as queuing layer to prioritize the way tasks are executed. * tasks are executed. Our implementation is just one simple way of implementing this pattern, there
* Our implementation is just one simple way of implementing this pattern, there are many variants possible * are many variants possible as described in its applications.
* as described in its applications.
* *
*/ */
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) {
AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>()); AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>());
/* /*
* A new task to calculate sum is received but as this is main thread, it should not block. * A new task to calculate sum is received but as this is main thread, it should not block. So
* So it passes it to the asynchronous task layer to compute and proceeds with handling other * it passes it to the asynchronous task layer to compute and proceeds with handling other
* incoming requests. This is particularly useful when main thread is waiting on Socket to receive * incoming requests. This is particularly useful when main thread is waiting on Socket to
* new incoming requests and does not wait for particular request to be completed before responding * receive new incoming requests and does not wait for particular request to be completed before
* to new request. * responding to new request.
*/ */
service.execute(new ArithmeticSumTask(1000)); service.execute(new ArithmeticSumTask(1000));
/* New task received, lets pass that to async layer for computation. So both requests will be /*
* New task received, lets pass that to async layer for computation. So both requests will be
* executed in parallel. * executed in parallel.
*/ */
service.execute(new ArithmeticSumTask(500)); service.execute(new ArithmeticSumTask(500));
@ -85,8 +84,8 @@ public class App {
} }
/* /*
* This is the long running task that is performed in background. In our example * This is the long running task that is performed in background. In our example the long
* the long running task is calculating arithmetic sum with artificial delay. * running task is calculating arithmetic sum with artificial delay.
*/ */
@Override @Override
public Long call() throws Exception { public Long call() throws Exception {
@ -94,11 +93,10 @@ public class App {
} }
/* /*
* This will be called in context of the main thread where some validations can be * This will be called in context of the main thread where some validations can be done
* done regarding the inputs. Such as it must be greater than 0. It's a small * regarding the inputs. Such as it must be greater than 0. It's a small computation which can
* computation which can be performed in main thread. If we did validated the input * be performed in main thread. If we did validated the input in background thread then we pay
* in background thread then we pay the cost of context switching * the cost of context switching which is much more than validating it in main thread.
* which is much more than validating it in main thread.
*/ */
@Override @Override
public void onPreCall() { public void onPreCall() {

View File

@ -3,41 +3,41 @@ package com.iluwatar.halfsynchalfasync;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Represents some computation that is performed asynchronously and its result. * Represents some computation that is performed asynchronously and its result. The computation is
* The computation is typically done is background threads and the result is posted * typically done is background threads and the result is posted back in form of callback. The
* back in form of callback. The callback does not implement {@code isComplete}, {@code cancel} * callback does not implement {@code isComplete}, {@code cancel} as it is out of scope of this
* as it is out of scope of this pattern. * pattern.
* *
* @param <O> type of result * @param <O> type of result
*/ */
public interface AsyncTask<O> extends Callable<O> { public interface AsyncTask<O> extends Callable<O> {
/** /**
* Is called in context of caller thread before call to {@link #call()}. Large * Is called in context of caller thread before call to {@link #call()}. Large tasks should not be
* tasks should not be performed in this method as it will block the caller thread. * performed in this method as it will block the caller thread. Small tasks such as validations
* Small tasks such as validations can be performed here so that the performance penalty * can be performed here so that the performance penalty of context switching is not incurred in
* of context switching is not incurred in case of invalid requests. * case of invalid requests.
*/ */
void onPreCall(); void onPreCall();
/** /**
* A callback called after the result is successfully computed by {@link #call()}. In our * A callback called after the result is successfully computed by {@link #call()}. In our
* implementation this method is called in context of background thread but in some variants, * implementation this method is called in context of background thread but in some variants, such
* such as Android where only UI thread can change the state of UI widgets, this method is called * as Android where only UI thread can change the state of UI widgets, this method is called in
* in context of UI thread. * context of UI thread.
*/ */
void onPostCall(O result); void onPostCall(O result);
/** /**
* A callback called if computing the task resulted in some exception. This method * A callback called if computing the task resulted in some exception. This method is called when
* is called when either of {@link #call()} or {@link #onPreCall()} throw any exception. * either of {@link #call()} or {@link #onPreCall()} throw any exception.
* *
* @param throwable error cause * @param throwable error cause
*/ */
void onError(Throwable throwable); void onError(Throwable throwable);
/** /**
* This is where the computation of task should reside. This method is called in context * This is where the computation of task should reside. This method is called in context of
* of background thread. * background thread.
*/ */
@Override @Override
O call() throws Exception; O call() throws Exception;

View File

@ -9,25 +9,25 @@ import java.util.concurrent.TimeUnit;
/** /**
* This is the asynchronous layer which does not block when a new request arrives. It just passes * This is the asynchronous layer which does not block when a new request arrives. It just passes
* the request to the synchronous layer which consists of a queue i.e. a {@link BlockingQueue} and * the request to the synchronous layer which consists of a queue i.e. a {@link BlockingQueue} and a
* a pool of threads i.e. {@link ThreadPoolExecutor}. Out of this pool of worker threads one of the * pool of threads i.e. {@link ThreadPoolExecutor}. Out of this pool of worker threads one of the
* thread picks up the task and executes it synchronously in background and the result is posted back * thread picks up the task and executes it synchronously in background and the result is posted
* to the caller via callback. * back to the caller via callback.
*/ */
public class AsynchronousService { public class AsynchronousService {
/* /*
* This represents the queuing layer as well as synchronous layer of the pattern. The thread * This represents the queuing layer as well as synchronous layer of the pattern. The thread pool
* pool contains worker threads which execute the tasks in blocking/synchronous manner. Long * contains worker threads which execute the tasks in blocking/synchronous manner. Long running
* running tasks should be performed in the background which does not affect the performance of * tasks should be performed in the background which does not affect the performance of main
* main thread. * thread.
*/ */
private ExecutorService service; private ExecutorService service;
/** /**
* Creates an asynchronous service using {@code workQueue} as communication channel between * Creates an asynchronous service using {@code workQueue} as communication channel between
* asynchronous layer and synchronous layer. Different types of queues such as Priority queue, * asynchronous layer and synchronous layer. Different types of queues such as Priority queue, can
* can be used to control the pattern of communication between the layers. * be used to control the pattern of communication between the layers.
*/ */
public AsynchronousService(BlockingQueue<Runnable> workQueue) { public AsynchronousService(BlockingQueue<Runnable> workQueue) {
service = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, workQueue); service = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, workQueue);
@ -38,8 +38,8 @@ public class AsynchronousService {
* A non-blocking method which performs the task provided in background and returns immediately. * A non-blocking method which performs the task provided in background and returns immediately.
* <p> * <p>
* On successful completion of task the result is posted back using callback method * On successful completion of task the result is posted back using callback method
* {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally * {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally due to
* due to some exception then the reason for error is posted back using callback method * some exception then the reason for error is posted back using callback method
* {@link AsyncTask#onError(Throwable)}. * {@link AsyncTask#onError(Throwable)}.
* <p> * <p>
* NOTE: The results are posted back in the context of background thread in this implementation. * NOTE: The results are posted back in the context of background thread in this implementation.
@ -57,11 +57,11 @@ public class AsynchronousService {
protected void done() { protected void done() {
super.done(); super.done();
try { try {
/* called in context of background thread. There is other variant possible /*
* where result is posted back and sits in the queue of caller thread which * called in context of background thread. There is other variant possible where result is
* then picks it up for processing. An example of such a system is Android OS, * posted back and sits in the queue of caller thread which then picks it up for
* where the UI elements can only be updated using UI thread. So result must be * processing. An example of such a system is Android OS, where the UI elements can only
* posted back in UI thread. * be updated using UI thread. So result must be posted back in UI thread.
*/ */
task.onPostCall(get()); task.onPostCall(get());
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -1,16 +1,14 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Base class for order processing filters. * Base class for order processing filters. Handles chain management.
* Handles chain management.
* *
*/ */
public abstract class AbstractFilter implements Filter { public abstract class AbstractFilter implements Filter {
private Filter next; private Filter next;
public AbstractFilter() { public AbstractFilter() {}
}
public AbstractFilter(Filter next) { public AbstractFilter(Filter next) {
this.next = next; this.next = next;

View File

@ -1,8 +1,9 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Concrete implementation of filter * Concrete implementation of filter This filter is responsible for checking/filtering the input in
* This filter is responsible for checking/filtering the input in the address field. * the address field.
*
* @author joshzambales * @author joshzambales
* *
*/ */

View File

@ -2,32 +2,27 @@ package com.iluwatar.intercepting.filter;
/** /**
* *
* When a request enters a Web application, it often must pass several entrance * When a request enters a Web application, it often must pass several entrance tests prior to the
* tests prior to the main processing stage. For example, * main processing stage. For example, - Has the client been authenticated? - Does the client have a
* - Has the client been authenticated? * valid session? - Is the client's IP address from a trusted network? - Does the request path
* - Does the client have a valid session? * violate any constraints? - What encoding does the client use to send the data? - Do we support
* - Is the client's IP address from a trusted network? * the browser type of the client? Some of these checks are tests, resulting in a yes or no answer
* - Does the request path violate any constraints? * that determines whether processing will continue. Other checks manipulate the incoming data
* - What encoding does the client use to send the data?
* - Do we support the browser type of the client?
* Some of these checks are tests, resulting in a yes or no answer that determines
* whether processing will continue. Other checks manipulate the incoming data
* stream into a form suitable for processing. * stream into a form suitable for processing.
* <p> * <p>
* The classic solution consists of a series of conditional checks, with any failed * The classic solution consists of a series of conditional checks, with any failed check aborting
* check aborting the request. Nested if/else statements are a standard strategy, * the request. Nested if/else statements are a standard strategy, but this solution leads to code
* but this solution leads to code fragility and a copy-and-paste style of programming, * fragility and a copy-and-paste style of programming, because the flow of the filtering and the
* because the flow of the filtering and the action of the filters is compiled into * action of the filters is compiled into the application.
* the application.
* <p> * <p>
* The key to solving this problem in a flexible and unobtrusive manner is to have a * The key to solving this problem in a flexible and unobtrusive manner is to have a simple
* simple mechanism for adding and removing processing components, in which each * mechanism for adding and removing processing components, in which each component completes a
* component completes a specific filtering action. This is the Intercepting Filter * specific filtering action. This is the Intercepting Filter pattern in action.
* pattern in action.
* <p> * <p>
* In this example we check whether the order request is valid through pre-processing * In this example we check whether the order request is valid through pre-processing done via
* done via {@link Filter}. Each field has its own corresponding {@link Filter} * {@link Filter}. Each field has its own corresponding {@link Filter}
* <p> * <p>
*
* @author joshzambales * @author joshzambales
* *
*/ */
@ -35,6 +30,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

@ -15,9 +15,11 @@ import javax.swing.JTextField;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
/** /**
* The Client class is responsible for handling the input and running them through filters inside the {@link FilterManager}. * The Client class is responsible for handling the input and running them through filters inside
* the {@link FilterManager}.
* *
* This is where {@link Filter}s come to play as the client pre-processes the request before being displayed in the {@link Target}. * This is where {@link Filter}s come to play as the client pre-processes the request before being
* displayed in the {@link Target}.
* *
* @author joshzambales * @author joshzambales
* *
@ -85,8 +87,8 @@ public class Client extends JFrame {
processButton.addActionListener(new ActionListener() { processButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Order order = new Order(jtFields[0].getText(), jtFields[1] Order order =
.getText(), jtAreas[0].getText(), new Order(jtFields[0].getText(), jtFields[1].getText(), jtAreas[0].getText(),
jtFields[2].getText(), jtAreas[1].getText()); jtFields[2].getText(), jtAreas[1].getText());
jl.setText(sendRequest(order)); jl.setText(sendRequest(order));
} }

View File

@ -1,9 +1,10 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Concrete implementation of filter * Concrete implementation of filter This filter checks for the contact field in which it checks if
* This filter checks for the contact field in which it checks if the input consist of numbers * the input consist of numbers and it also checks if the input follows the length constraint (11
* and it also checks if the input follows the length constraint (11 digits) * digits)
*
* @author joshzambales * @author joshzambales
* *
*/ */
@ -12,8 +13,7 @@ public class ContactFilter extends AbstractFilter {
@Override @Override
public String execute(Order order) { public String execute(Order order) {
String result = super.execute(order); String result = super.execute(order);
if (order.getContactNumber() == null if (order.getContactNumber() == null || order.getContactNumber().isEmpty()
|| order.getContactNumber().isEmpty()
|| order.getContactNumber().matches(".*[^\\d]+.*") || order.getContactNumber().matches(".*[^\\d]+.*")
|| order.getContactNumber().length() != 11) { || order.getContactNumber().length() != 11) {
return result + "Invalid contact number! "; return result + "Invalid contact number! ";

View File

@ -1,8 +1,8 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Concrete implementation of filter * Concrete implementation of filter This checks for the deposit code
* This checks for the deposit code *
* @author joshzambales * @author joshzambales
* *
*/ */

View File

@ -1,9 +1,8 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Filters perform certain tasks prior or after execution of * Filters perform certain tasks prior or after execution of request by request handler. In this
* request by request handler. In this case, before the request is handled by * case, before the request is handled by the target, the request undergoes through each Filter
* the target, the request undergoes through each Filter
* *
* @author joshzambales * @author joshzambales
* *
@ -12,6 +11,7 @@ public interface Filter {
/** /**
* Execute order processing filter. * Execute order processing filter.
*
* @param order * @param order
* @return empty string on success, otherwise error message. * @return empty string on success, otherwise error message.
*/ */
@ -19,18 +19,21 @@ public interface Filter {
/** /**
* Set next filter in chain after this. * Set next filter in chain after this.
*
* @param filter * @param filter
*/ */
void setNext(Filter filter); void setNext(Filter filter);
/** /**
* Get next filter in chain after this. * Get next filter in chain after this.
*
* @return * @return
*/ */
Filter getNext(); Filter getNext();
/** /**
* Get last filter in the chain. * Get last filter in the chain.
*
* @return * @return
*/ */
Filter getLast(); Filter getLast();

View File

@ -1,8 +1,8 @@
package com.iluwatar.intercepting.filter; package com.iluwatar.intercepting.filter;
/** /**
* Concrete implementation of filter. This filter checks if the input in the Name * Concrete implementation of filter. This filter checks if the input in the Name field is valid.
* field is valid. (alphanumeric) * (alphanumeric)
* *
* @author joshzambales * @author joshzambales
* *
@ -12,7 +12,8 @@ public class NameFilter extends AbstractFilter {
@Override @Override
public String execute(Order order) { public String execute(Order order) {
String result = super.execute(order); String result = super.execute(order);
if (order.getName() == null || order.getName().isEmpty() || order.getName().matches(".*[^\\w|\\s]+.*")) { if (order.getName() == null || order.getName().isEmpty()
|| order.getName().matches(".*[^\\w|\\s]+.*")) {
return result + "Invalid order! "; return result + "Invalid order! ";
} else { } else {
return result; return result;

View File

@ -12,8 +12,7 @@ public class Order {
private String depositNumber; private String depositNumber;
private String order; private String order;
public Order() { public Order() {}
}
public Order(String name, String contactNumber, String address, String depositNumber, String order) { public Order(String name, String contactNumber, String address, String depositNumber, String order) {
this.name = name; this.name = name;

View File

@ -33,8 +33,9 @@ public class Target extends JFrame {
super("Order System"); super("Order System");
setDefaultCloseOperation(EXIT_ON_CLOSE); setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(640, 480); setSize(640, 480);
dtm = new DefaultTableModel(new Object[] { "Name", "Contact Number", dtm =
"Address", "Deposit Number", "Order" }, 0); new DefaultTableModel(new Object[] {"Name", "Contact Number", "Address", "Deposit Number",
"Order"}, 0);
jt = new JTable(dtm); jt = new JTable(dtm);
del = new JButton("Delete"); del = new JButton("Delete");
setup(); setup();
@ -59,8 +60,7 @@ public class Target extends JFrame {
} }
public void execute(String[] request) { public void execute(String[] request) {
dtm.addRow(new Object[] { request[0], request[1], request[2], dtm.addRow(new Object[] {request[0], request[1], request[2], request[3], request[4]});
request[3], request[4] });
} }
class DListener implements ActionListener { class DListener implements ActionListener {

View File

@ -4,14 +4,13 @@ import java.util.Stack;
/** /**
* *
* The Interpreter pattern is a design pattern that specifies how to evaluate sentences * The Interpreter pattern is a design pattern that specifies how to evaluate sentences in a
* in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) * language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a
* in a specialized computer language. The syntax tree of a sentence in the language is an * specialized computer language. The syntax tree of a sentence in the language is an instance of
* instance of the composite pattern and is used to evaluate (interpret) the sentence for a * the composite pattern and is used to evaluate (interpret) the sentence for a client.
* client.
* <p> * <p>
* In this example we use the Interpreter pattern to break sentences into expressions * In this example we use the Interpreter pattern to break sentences into expressions (
* ({@link Expression}) that can be evaluated and as a whole form the result. * {@link Expression}) that can be evaluated and as a whole form the result.
* *
*/ */
public class App { public class App {
@ -20,8 +19,8 @@ public class App {
* *
* Program entry point. * Program entry point.
* <p> * <p>
* Expressions can be evaluated using prefix, infix or postfix notations * Expressions can be evaluated using prefix, infix or postfix notations This sample uses postfix,
* This sample uses postfix, where operator comes after the operands * where operator comes after the operands
* *
* @param args command line args * @param args command line args
* *
@ -35,36 +34,28 @@ public class App {
if (isOperator(s)) { if (isOperator(s)) {
Expression rightExpression = stack.pop(); Expression rightExpression = stack.pop();
Expression leftExpression = stack.pop(); Expression leftExpression = stack.pop();
System.out System.out.println(String.format("popped from stack left: %d right: %d",
.println(String.format( leftExpression.interpret(), rightExpression.interpret()));
"popped from stack left: %d right: %d", Expression operator = getOperatorInstance(s, leftExpression, rightExpression);
leftExpression.interpret(),
rightExpression.interpret()));
Expression operator = getOperatorInstance(s, leftExpression,
rightExpression);
System.out.println(String.format("operator: %s", operator)); System.out.println(String.format("operator: %s", operator));
int result = operator.interpret(); int result = operator.interpret();
NumberExpression resultExpression = new NumberExpression(result); NumberExpression resultExpression = new NumberExpression(result);
stack.push(resultExpression); stack.push(resultExpression);
System.out.println(String.format("push result to stack: %d", System.out.println(String.format("push result to stack: %d", resultExpression.interpret()));
resultExpression.interpret()));
} else { } else {
Expression i = new NumberExpression(s); Expression i = new NumberExpression(s);
stack.push(i); stack.push(i);
System.out.println(String.format("push to stack: %d", System.out.println(String.format("push to stack: %d", i.interpret()));
i.interpret()));
} }
} }
System.out System.out.println(String.format("result: %d", stack.pop().interpret()));
.println(String.format("result: %d", stack.pop().interpret()));
} }
public static boolean isOperator(String s) { public static boolean isOperator(String s) {
return s.equals("+") || s.equals("-") || s.equals("*"); return s.equals("+") || s.equals("-") || s.equals("*");
} }
public static Expression getOperatorInstance(String s, Expression left, public static Expression getOperatorInstance(String s, Expression left, Expression right) {
Expression right) {
switch (s) { switch (s) {
case "+": case "+":
return new PlusExpression(left, right); return new PlusExpression(left, right);

View File

@ -10,8 +10,7 @@ public class MultiplyExpression extends Expression {
private Expression leftExpression; private Expression leftExpression;
private Expression rightExpression; private Expression rightExpression;
public MultiplyExpression(Expression leftExpression, public MultiplyExpression(Expression leftExpression, Expression rightExpression) {
Expression rightExpression) {
this.leftExpression = leftExpression; this.leftExpression = leftExpression;
this.rightExpression = rightExpression; this.rightExpression = rightExpression;
} }

View File

@ -26,5 +26,4 @@ public class NumberExpression extends Expression {
public String toString() { public String toString() {
return "number"; return "number";
} }
} }

View File

@ -24,5 +24,4 @@ public class PlusExpression extends Expression {
public String toString() { public String toString() {
return "+"; return "+";
} }
} }

View File

@ -2,19 +2,19 @@ package com.iluwatar.iterator;
/** /**
* *
* The Iterator pattern is a design pattern in which an iterator is used to * The Iterator pattern is a design pattern in which an iterator is used to traverse a container and
* traverse a container and access the container's elements. The Iterator pattern * access the container's elements. The Iterator pattern decouples algorithms from containers.
* decouples algorithms from containers.
* <p> * <p>
* In this example the Iterator ({@link ItemIterator}) adds abstraction layer on * In this example the Iterator ({@link ItemIterator}) adds abstraction layer on top of a collection
* top of a collection ({@link TreasureChest}). This way the collection can change * ({@link TreasureChest}). This way the collection can change its internal implementation without
* its internal implementation without affecting its clients. * affecting its clients.
* *
*/ */
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

@ -44,8 +44,7 @@ public class TreasureChestItemIterator implements ItemIterator {
tempIdx = -1; tempIdx = -1;
break; break;
} }
if (type.equals(ItemType.ANY) if (type.equals(ItemType.ANY) || items.get(tempIdx).getType().equals(type)) {
|| items.get(tempIdx).getType().equals(type)) {
break; break;
} }
} }

View File

@ -4,32 +4,31 @@ import java.util.Arrays;
/** /**
* *
* Layers is an architectural style where software responsibilities are * Layers is an architectural style where software responsibilities are divided among the different
* divided among the different layers of the application. * layers of the application.
* <p> * <p>
* This example demonstrates a traditional 3-layer architecture consisting of data access * This example demonstrates a traditional 3-layer architecture consisting of data access layer,
* layer, business layer and presentation layer. * business layer and presentation layer.
* <p> * <p>
* The data access layer is formed of Spring Data repositories <code>CakeDao</code>, <code>CakeToppingDao</code> and * The data access layer is formed of Spring Data repositories <code>CakeDao</code>,
* <code>CakeLayerDao</code>. The repositories can be used for CRUD operations on cakes, cake toppings * <code>CakeToppingDao</code> and <code>CakeLayerDao</code>. The repositories can be used for CRUD
* and cake layers respectively. * operations on cakes, cake toppings and cake layers respectively.
* <p> * <p>
* The business layer is built on top of the data access layer. <code>CakeBakingService</code> offers * The business layer is built on top of the data access layer. <code>CakeBakingService</code>
* methods to retrieve available cake toppings and cake layers and baked cakes. Also the * offers methods to retrieve available cake toppings and cake layers and baked cakes. Also the
* service is used to create new cakes out of cake toppings and cake layers. * service is used to create new cakes out of cake toppings and cake layers.
* <p> * <p>
* The presentation layer is built on the business layer and in this example it simply lists * The presentation layer is built on the business layer and in this example it simply lists the
* the cakes that have been baked. * cakes that have been baked.
* <p> * <p>
* We have applied so called strict layering which means that the layers can only access * We have applied so called strict layering which means that the layers can only access the classes
* the classes directly beneath them. This leads the solution to create an additional set of * directly beneath them. This leads the solution to create an additional set of DTOs (
* DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) * <code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) to translate
* to translate data between layers. In other words, <code>CakeBakingService</code> cannot * data between layers. In other words, <code>CakeBakingService</code> cannot return entities (
* return entities (<code>Cake</code>, <code>CakeTopping</code>, <code>CakeLayer</code>) * <code>Cake</code>, <code>CakeTopping</code>, <code>CakeLayer</code>) directly since these reside
* directly since these reside on data access layer but instead translates these into business * on data access layer but instead translates these into business layer DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) and returns them instead. This way
* layer DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>) * the presentation layer does not have any knowledge of other layers than the business layer and
* and returns them instead. This way the presentation layer does not have any knowledge of * thus is not affected by changes to them.
* other layers than the business layer and thus is not affected by changes to them.
* *
* @see Cake * @see Cake
* @see CakeTopping * @see CakeTopping
@ -49,6 +48,7 @@ public class App {
/** /**
* Application entry point * Application entry point
*
* @param args Command line parameters * @param args Command line parameters
*/ */
public static void main(String[] args) { public static void main(String[] args) {
@ -63,6 +63,7 @@ public class App {
/** /**
* Initializes the example data * Initializes the example data
*
* @param cakeBakingService * @param cakeBakingService
*/ */
private static void initializeData(CakeBakingService cakeBakingService) { private static void initializeData(CakeBakingService cakeBakingService) {
@ -76,17 +77,18 @@ public class App {
cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350)); cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350));
cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350)); cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350));
CakeInfo cake1 = new CakeInfo(new CakeToppingInfo("candies", 0), CakeInfo cake1 =
Arrays.asList(new CakeLayerInfo("chocolate", 0), new CakeLayerInfo("banana", 0), new CakeInfo(new CakeToppingInfo("candies", 0), Arrays.asList(new CakeLayerInfo(
new CakeLayerInfo("strawberry", 0))); "chocolate", 0), new CakeLayerInfo("banana", 0), new CakeLayerInfo("strawberry", 0)));
try { try {
cakeBakingService.bakeNewCake(cake1); cakeBakingService.bakeNewCake(cake1);
} catch (CakeBakingException e) { } catch (CakeBakingException e) {
e.printStackTrace(); e.printStackTrace();
} }
CakeInfo cake2 = new CakeInfo(new CakeToppingInfo("cherry", 0), CakeInfo cake2 =
Arrays.asList(new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0), new CakeInfo(new CakeToppingInfo("cherry", 0), Arrays.asList(
new CakeLayerInfo("strawberry", 0))); new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0), new CakeLayerInfo(
"strawberry", 0)));
try { try {
cakeBakingService.bakeNewCake(cake2); cakeBakingService.bakeNewCake(cake2);
} catch (CakeBakingException e) { } catch (CakeBakingException e) {

View File

@ -9,8 +9,7 @@ public class CakeBakingException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public CakeBakingException() { public CakeBakingException() {}
}
public CakeBakingException(String message) { public CakeBakingException(String message) {
super(message); super(message);

Some files were not shown because too many files have changed in this diff Show More