Merge pull request #281 from ankurkaushal/master
Reformat according to google style guide
This commit is contained in:
commit
fe63c9cec4
@ -3,80 +3,78 @@ 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 {
|
||||||
|
|
||||||
private King king;
|
private King king;
|
||||||
private Castle castle;
|
private Castle castle;
|
||||||
private Army army;
|
private Army army;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates kingdom
|
* Creates kingdom
|
||||||
* @param factory
|
*
|
||||||
*/
|
* @param factory
|
||||||
public void createKingdom(final KingdomFactory factory) {
|
*/
|
||||||
setKing(factory.createKing());
|
public void createKingdom(final KingdomFactory factory) {
|
||||||
setCastle(factory.createCastle());
|
setKing(factory.createKing());
|
||||||
setArmy(factory.createArmy());
|
setCastle(factory.createCastle());
|
||||||
}
|
setArmy(factory.createArmy());
|
||||||
|
}
|
||||||
ElfKingdomFactory getElfKingdomFactory() {
|
|
||||||
return new ElfKingdomFactory();
|
ElfKingdomFactory getElfKingdomFactory() {
|
||||||
}
|
return new ElfKingdomFactory();
|
||||||
|
}
|
||||||
OrcKingdomFactory getOrcKingdomFactory() {
|
|
||||||
return new OrcKingdomFactory();
|
OrcKingdomFactory getOrcKingdomFactory() {
|
||||||
}
|
return new OrcKingdomFactory();
|
||||||
|
}
|
||||||
King getKing(final KingdomFactory factory) {
|
|
||||||
return factory.createKing();
|
King getKing(final KingdomFactory factory) {
|
||||||
}
|
return factory.createKing();
|
||||||
|
}
|
||||||
Castle getCastle(final KingdomFactory factory) {
|
|
||||||
return factory.createCastle();
|
Castle getCastle(final KingdomFactory factory) {
|
||||||
}
|
return factory.createCastle();
|
||||||
|
}
|
||||||
Army getArmy(final KingdomFactory factory) {
|
|
||||||
return factory.createArmy();
|
Army getArmy(final KingdomFactory factory) {
|
||||||
}
|
return factory.createArmy();
|
||||||
|
}
|
||||||
public King getKing() {
|
|
||||||
return king;
|
public King getKing() {
|
||||||
}
|
return king;
|
||||||
|
}
|
||||||
private void setKing(final King king) {
|
|
||||||
this.king = king;
|
private void setKing(final King king) {
|
||||||
}
|
this.king = king;
|
||||||
|
}
|
||||||
public Castle getCastle() {
|
|
||||||
return castle;
|
public Castle getCastle() {
|
||||||
}
|
return castle;
|
||||||
|
}
|
||||||
private void setCastle(final Castle castle) {
|
|
||||||
this.castle = castle;
|
private void setCastle(final Castle castle) {
|
||||||
}
|
this.castle = castle;
|
||||||
|
}
|
||||||
public Army getArmy() {
|
|
||||||
return army;
|
public Army getArmy() {
|
||||||
}
|
return army;
|
||||||
|
}
|
||||||
private void setArmy(final Army army) {
|
|
||||||
this.army = army;
|
private void setArmy(final Army army) {
|
||||||
}
|
this.army = army;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public interface Army {
|
public interface Army {
|
||||||
|
|
||||||
String getDescription();
|
String getDescription();
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public interface Castle {
|
public interface Castle {
|
||||||
|
|
||||||
String getDescription();
|
String getDescription();
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class ElfArmy implements Army {
|
public class ElfArmy implements Army {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Elven Army!";
|
static final String DESCRIPTION = "This is the Elven Army!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class ElfCastle implements Castle {
|
public class ElfCastle implements Castle {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Elven castle!";
|
static final String DESCRIPTION = "This is the Elven castle!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class ElfKing implements King {
|
public class ElfKing implements King {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Elven king!";
|
static final String DESCRIPTION = "This is the Elven king!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,16 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class ElfKingdomFactory implements KingdomFactory {
|
public class ElfKingdomFactory implements KingdomFactory {
|
||||||
|
|
||||||
public Castle createCastle() {
|
public Castle createCastle() {
|
||||||
return new ElfCastle();
|
return new ElfCastle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public King createKing() {
|
public King createKing() {
|
||||||
return new ElfKing();
|
return new ElfKing();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Army createArmy() {
|
public Army createArmy() {
|
||||||
return new ElfArmy();
|
return new ElfArmy();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public interface King {
|
public interface King {
|
||||||
|
|
||||||
String getDescription();
|
String getDescription();
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public interface KingdomFactory {
|
public interface KingdomFactory {
|
||||||
|
|
||||||
Castle createCastle();
|
Castle createCastle();
|
||||||
|
|
||||||
King createKing();
|
King createKing();
|
||||||
|
|
||||||
Army createArmy();
|
Army createArmy();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class OrcArmy implements Army {
|
public class OrcArmy implements Army {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Orc Army!";
|
static final String DESCRIPTION = "This is the Orc Army!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class OrcCastle implements Castle {
|
public class OrcCastle implements Castle {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Orc castle!";
|
static final String DESCRIPTION = "This is the Orc castle!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class OrcKing implements King {
|
public class OrcKing implements King {
|
||||||
|
|
||||||
static final String DESCRIPTION = "This is the Orc king!";
|
static final String DESCRIPTION = "This is the Orc king!";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESCRIPTION;
|
return DESCRIPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,15 @@ package com.iluwatar.abstractfactory;
|
|||||||
*/
|
*/
|
||||||
public class OrcKingdomFactory implements KingdomFactory {
|
public class OrcKingdomFactory implements KingdomFactory {
|
||||||
|
|
||||||
public Castle createCastle() {
|
public Castle createCastle() {
|
||||||
return new OrcCastle();
|
return new OrcCastle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public King createKing() {
|
public King createKing() {
|
||||||
return new OrcKing();
|
return new OrcKing();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Army createArmy() {
|
|
||||||
return new OrcArmy();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public Army createArmy() {
|
||||||
|
return new OrcArmy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -7,71 +8,71 @@ import org.junit.Test;
|
|||||||
|
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
private App app = new App();
|
private App app = new App();
|
||||||
private KingdomFactory elfFactory;
|
private KingdomFactory elfFactory;
|
||||||
private KingdomFactory orcFactory;
|
private KingdomFactory orcFactory;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
elfFactory = app.getElfKingdomFactory();
|
elfFactory = app.getElfKingdomFactory();
|
||||||
orcFactory = app.getOrcKingdomFactory();
|
orcFactory = app.getOrcKingdomFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void king() {
|
public void king() {
|
||||||
final King elfKing = app.getKing(elfFactory);
|
final King elfKing = app.getKing(elfFactory);
|
||||||
assertTrue(elfKing instanceof ElfKing);
|
assertTrue(elfKing instanceof ElfKing);
|
||||||
assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
|
assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
|
||||||
final King orcKing = app.getKing(orcFactory);
|
final King orcKing = app.getKing(orcFactory);
|
||||||
assertTrue(orcKing instanceof OrcKing);
|
assertTrue(orcKing instanceof OrcKing);
|
||||||
assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
|
assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void castle() {
|
public void castle() {
|
||||||
final Castle elfCastle = app.getCastle(elfFactory);
|
final Castle elfCastle = app.getCastle(elfFactory);
|
||||||
assertTrue(elfCastle instanceof ElfCastle);
|
assertTrue(elfCastle instanceof ElfCastle);
|
||||||
assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
|
assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
|
||||||
final Castle orcCastle = app.getCastle(orcFactory);
|
final Castle orcCastle = app.getCastle(orcFactory);
|
||||||
assertTrue(orcCastle instanceof OrcCastle);
|
assertTrue(orcCastle instanceof OrcCastle);
|
||||||
assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
|
assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void army() {
|
public void army() {
|
||||||
final Army elfArmy = app.getArmy(elfFactory);
|
final Army elfArmy = app.getArmy(elfFactory);
|
||||||
assertTrue(elfArmy instanceof ElfArmy);
|
assertTrue(elfArmy instanceof ElfArmy);
|
||||||
assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
|
assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
|
||||||
final Army orcArmy = app.getArmy(orcFactory);
|
final Army orcArmy = app.getArmy(orcFactory);
|
||||||
assertTrue(orcArmy instanceof OrcArmy);
|
assertTrue(orcArmy instanceof OrcArmy);
|
||||||
assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
|
assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createElfKingdom() {
|
public void createElfKingdom() {
|
||||||
app.createKingdom(elfFactory);
|
app.createKingdom(elfFactory);
|
||||||
final King king = app.getKing();
|
final King king = app.getKing();
|
||||||
final Castle castle = app.getCastle();
|
final Castle castle = app.getCastle();
|
||||||
final Army army = app.getArmy();
|
final Army army = app.getArmy();
|
||||||
assertTrue(king instanceof ElfKing);
|
assertTrue(king instanceof ElfKing);
|
||||||
assertEquals(ElfKing.DESCRIPTION, king.getDescription());
|
assertEquals(ElfKing.DESCRIPTION, king.getDescription());
|
||||||
assertTrue(castle instanceof ElfCastle);
|
assertTrue(castle instanceof ElfCastle);
|
||||||
assertEquals(ElfCastle.DESCRIPTION, castle.getDescription());
|
assertEquals(ElfCastle.DESCRIPTION, castle.getDescription());
|
||||||
assertTrue(army instanceof ElfArmy);
|
assertTrue(army instanceof ElfArmy);
|
||||||
assertEquals(ElfArmy.DESCRIPTION, army.getDescription());
|
assertEquals(ElfArmy.DESCRIPTION, army.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createOrcKingdom() {
|
public void createOrcKingdom() {
|
||||||
app.createKingdom(orcFactory);
|
app.createKingdom(orcFactory);
|
||||||
final King king = app.getKing();
|
final King king = app.getKing();
|
||||||
final Castle castle = app.getCastle();
|
final Castle castle = app.getCastle();
|
||||||
final Army army = app.getArmy();
|
final Army army = app.getArmy();
|
||||||
assertTrue(king instanceof OrcKing);
|
assertTrue(king instanceof OrcKing);
|
||||||
assertEquals(OrcKing.DESCRIPTION, king.getDescription());
|
assertEquals(OrcKing.DESCRIPTION, king.getDescription());
|
||||||
assertTrue(castle instanceof OrcCastle);
|
assertTrue(castle instanceof OrcCastle);
|
||||||
assertEquals(OrcCastle.DESCRIPTION, castle.getDescription());
|
assertEquals(OrcCastle.DESCRIPTION, castle.getDescription());
|
||||||
assertTrue(army instanceof OrcArmy);
|
assertTrue(army instanceof OrcArmy);
|
||||||
assertEquals(OrcArmy.DESCRIPTION, army.getDescription());
|
assertEquals(OrcArmy.DESCRIPTION, army.getDescription());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,29 @@ 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) {
|
*/
|
||||||
Engineer manager = new GnomeEngineeringManager();
|
public static void main(String[] args) {
|
||||||
manager.operateDevice();
|
Engineer manager = new GnomeEngineeringManager();
|
||||||
}
|
manager.operateDevice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,5 @@ package com.iluwatar.adapter;
|
|||||||
*/
|
*/
|
||||||
public interface Engineer {
|
public interface Engineer {
|
||||||
|
|
||||||
void operateDevice();
|
void operateDevice();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,22 @@ 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 {
|
||||||
|
|
||||||
private GoblinGlider glider;
|
private GoblinGlider glider;
|
||||||
|
|
||||||
public GnomeEngineer() {
|
public GnomeEngineer() {
|
||||||
glider = new GoblinGlider();
|
glider = new GoblinGlider();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void operateDevice() {
|
|
||||||
glider.attachGlider();
|
|
||||||
glider.gainSpeed();
|
|
||||||
glider.takeOff();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void operateDevice() {
|
||||||
|
glider.attachGlider();
|
||||||
|
glider.gainSpeed();
|
||||||
|
glider.takeOff();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,14 @@ package com.iluwatar.adapter;
|
|||||||
*/
|
*/
|
||||||
public class GnomeEngineeringManager implements Engineer {
|
public class GnomeEngineeringManager implements Engineer {
|
||||||
|
|
||||||
private Engineer engineer;
|
private Engineer engineer;
|
||||||
|
|
||||||
public GnomeEngineeringManager() {
|
public GnomeEngineeringManager() {
|
||||||
engineer = new GnomeEngineer();
|
engineer = new GnomeEngineer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void operateDevice() {
|
public void operateDevice() {
|
||||||
engineer.operateDevice();
|
engineer.operateDevice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,15 @@ package com.iluwatar.adapter;
|
|||||||
*/
|
*/
|
||||||
public class GoblinGlider {
|
public class GoblinGlider {
|
||||||
|
|
||||||
public void attachGlider() {
|
public void attachGlider() {
|
||||||
System.out.println("Glider attached.");
|
System.out.println("Glider attached.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gainSpeed() {
|
public void gainSpeed() {
|
||||||
System.out.println("Gaining speed.");
|
System.out.println("Gaining speed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void takeOff() {
|
public void takeOff() {
|
||||||
System.out.println("Lift-off!");
|
System.out.println("Lift-off!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.adapter.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
@ -32,66 +33,68 @@ import java.util.concurrent.Callable;
|
|||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// construct a new executor that will run async tasks
|
// construct a new executor that will run async tasks
|
||||||
AsyncExecutor executor = new ThreadAsyncExecutor();
|
AsyncExecutor executor = new ThreadAsyncExecutor();
|
||||||
|
|
||||||
// start few async tasks with varying processing times, two last with callback handlers
|
// start few async tasks with varying processing times, two last with callback handlers
|
||||||
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
|
||||||
log("Some hard work done");
|
log("Some hard work done");
|
||||||
|
|
||||||
// wait for completion of the tasks
|
// wait for completion of the tasks
|
||||||
Integer result1 = executor.endProcess(asyncResult1);
|
Integer result1 = executor.endProcess(asyncResult1);
|
||||||
String result2 = executor.endProcess(asyncResult2);
|
String result2 = executor.endProcess(asyncResult2);
|
||||||
Long result3 = executor.endProcess(asyncResult3);
|
Long result3 = executor.endProcess(asyncResult3);
|
||||||
asyncResult4.await();
|
asyncResult4.await();
|
||||||
asyncResult5.await();
|
asyncResult5.await();
|
||||||
|
|
||||||
// log the results of the tasks, callbacks log immediately when complete
|
// log the results of the tasks, callbacks log immediately when complete
|
||||||
log("Result 1: " + result1);
|
log("Result 1: " + result1);
|
||||||
log("Result 2: " + result2);
|
log("Result 2: " + result2);
|
||||||
log("Result 3: " + result3);
|
log("Result 3: " + result3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a callable that lazily evaluates to given value with artificial delay.
|
* Creates a callable that lazily evaluates to given value with artificial delay.
|
||||||
*
|
*
|
||||||
* @param value value to evaluate
|
* @param value value to evaluate
|
||||||
* @param delayMillis artificial delay in milliseconds
|
* @param delayMillis artificial delay in milliseconds
|
||||||
* @return new callable for lazy evaluation
|
* @return new callable for lazy evaluation
|
||||||
*/
|
*/
|
||||||
private static <T> Callable<T> lazyval(T value, long delayMillis) {
|
private static <T> Callable<T> lazyval(T value, long delayMillis) {
|
||||||
return () -> {
|
return () -> {
|
||||||
Thread.sleep(delayMillis);
|
Thread.sleep(delayMillis);
|
||||||
log("Task completed with: " + value);
|
log("Task completed with: " + value);
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a simple callback that logs the complete status of the async result.
|
* Creates a simple callback that logs the complete status of the async result.
|
||||||
*
|
*
|
||||||
* @param name callback name
|
* @param name callback name
|
||||||
* @return new async callback
|
* @return new async callback
|
||||||
*/
|
*/
|
||||||
private static <T> AsyncCallback<T> callback(String name) {
|
private static <T> AsyncCallback<T> callback(String name) {
|
||||||
return (value, ex) -> {
|
return (value, ex) -> {
|
||||||
if (ex.isPresent()) {
|
if (ex.isPresent()) {
|
||||||
log(name + " failed: " + ex.map(Exception::getMessage).orElse(""));
|
log(name + " failed: " + ex.map(Exception::getMessage).orElse(""));
|
||||||
} else {
|
} else {
|
||||||
log(name + ": " + value);
|
log(name + ": " + value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg));
|
System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,11 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public interface AsyncCallback<T> {
|
public interface AsyncCallback<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complete handler which is executed when async task is completed or fails execution.
|
* Complete handler which is executed when async task is completed or fails execution.
|
||||||
*
|
*
|
||||||
* @param value the evaluated value from async task, undefined when execution fails
|
* @param value the evaluated value from async task, undefined when execution fails
|
||||||
* @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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,33 +10,32 @@ import java.util.concurrent.ExecutionException;
|
|||||||
*/
|
*/
|
||||||
public interface AsyncExecutor {
|
public interface AsyncExecutor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts processing of an async task. Returns immediately with async result.
|
* Starts processing of an async task. Returns immediately with async result.
|
||||||
*
|
*
|
||||||
* @param task task to be executed asynchronously
|
* @param task task to be executed asynchronously
|
||||||
* @return async result for the task
|
* @return async result for the task
|
||||||
*/
|
*/
|
||||||
<T> AsyncResult<T> startProcess(Callable<T> task);
|
<T> AsyncResult<T> startProcess(Callable<T> task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts processing of an async task. Returns immediately with async result. Executes callback
|
* Starts processing of an async task. Returns immediately with async result. Executes callback
|
||||||
* when the task is completed.
|
* when the task is completed.
|
||||||
*
|
*
|
||||||
* @param task task to be executed asynchronously
|
* @param task task to be executed asynchronously
|
||||||
* @param callback callback to be executed on task completion
|
* @param callback callback to be executed on task completion
|
||||||
* @return async result for the task
|
* @return async result for the task
|
||||||
*/
|
*/
|
||||||
<T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback);
|
<T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback);
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends processing of an async task. Blocks the current thread if necessary and returns the
|
|
||||||
* evaluated value of the completed task.
|
|
||||||
*
|
|
||||||
* @param asyncResult async result of a task
|
|
||||||
* @return evaluated value of the completed task
|
|
||||||
* @throws ExecutionException if execution has failed, containing the root cause
|
|
||||||
* @throws InterruptedException if the execution is interrupted
|
|
||||||
*/
|
|
||||||
<T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends processing of an async task. Blocks the current thread if necessary and returns the
|
||||||
|
* evaluated value of the completed task.
|
||||||
|
*
|
||||||
|
* @param asyncResult async result of a task
|
||||||
|
* @return evaluated value of the completed task
|
||||||
|
* @throws ExecutionException if execution has failed, containing the root cause
|
||||||
|
* @throws InterruptedException if the execution is interrupted
|
||||||
|
*/
|
||||||
|
<T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
|
||||||
}
|
}
|
||||||
|
@ -10,26 +10,26 @@ import java.util.concurrent.ExecutionException;
|
|||||||
*/
|
*/
|
||||||
public interface AsyncResult<T> {
|
public interface AsyncResult<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status of the async task execution.
|
* Status of the async task execution.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if execution is completed or failed
|
* @return <code>true</code> if execution is completed or failed
|
||||||
*/
|
*/
|
||||||
boolean isCompleted();
|
boolean isCompleted();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of completed async task.
|
* Gets the value of completed async task.
|
||||||
*
|
*
|
||||||
* @return evaluated value or throws ExecutionException if execution has failed
|
* @return evaluated value or throws ExecutionException if execution has failed
|
||||||
* @throws ExecutionException if execution has failed, containing the root cause
|
* @throws ExecutionException if execution has failed, containing the root cause
|
||||||
* @throws IllegalStateException if execution is not completed
|
* @throws IllegalStateException if execution is not completed
|
||||||
*/
|
*/
|
||||||
T getValue() throws ExecutionException;
|
T getValue() throws ExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks the current thread until the async task is completed.
|
* Blocks the current thread until the async task is completed.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if the execution is interrupted
|
* @throws InterruptedException if the execution is interrupted
|
||||||
*/
|
*/
|
||||||
void await() throws InterruptedException;
|
void await() throws InterruptedException;
|
||||||
}
|
}
|
||||||
|
@ -12,116 +12,117 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
*/
|
*/
|
||||||
public class ThreadAsyncExecutor implements AsyncExecutor {
|
public class ThreadAsyncExecutor implements AsyncExecutor {
|
||||||
|
|
||||||
/** Index for thread naming */
|
/** Index for thread naming */
|
||||||
private final AtomicInteger idx = new AtomicInteger(0);
|
private final AtomicInteger idx = new AtomicInteger(0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncResult<T> startProcess(Callable<T> task) {
|
public <T> AsyncResult<T> startProcess(Callable<T> task) {
|
||||||
return startProcess(task, null);
|
return startProcess(task, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
|
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
|
||||||
CompletableResult<T> result = new CompletableResult<>(callback);
|
CompletableResult<T> result = new CompletableResult<>(callback);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
result.setValue(task.call());
|
result.setValue(task.call());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
result.setException(ex);
|
result.setException(ex);
|
||||||
}
|
}
|
||||||
}, "executor-" + idx.incrementAndGet()).start();
|
}, "executor-" + idx.incrementAndGet()).start();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException {
|
public <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException,
|
||||||
if (asyncResult.isCompleted()) {
|
InterruptedException {
|
||||||
return asyncResult.getValue();
|
if (asyncResult.isCompleted()) {
|
||||||
} else {
|
return asyncResult.getValue();
|
||||||
asyncResult.await();
|
} else {
|
||||||
return asyncResult.getValue();
|
asyncResult.await();
|
||||||
}
|
return asyncResult.getValue();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
* @see java.util.concurrent.CompletableFuture
|
* @see java.util.concurrent.CompletableFuture
|
||||||
*/
|
*/
|
||||||
private static class CompletableResult<T> implements AsyncResult<T> {
|
private static class CompletableResult<T> implements AsyncResult<T> {
|
||||||
|
|
||||||
static final int RUNNING = 1;
|
static final int RUNNING = 1;
|
||||||
static final int FAILED = 2;
|
static final int FAILED = 2;
|
||||||
static final int COMPLETED = 3;
|
static final int COMPLETED = 3;
|
||||||
|
|
||||||
final Object lock;
|
final Object lock;
|
||||||
final Optional<AsyncCallback<T>> callback;
|
final Optional<AsyncCallback<T>> callback;
|
||||||
|
|
||||||
volatile int state = RUNNING;
|
volatile int state = RUNNING;
|
||||||
T value;
|
T value;
|
||||||
Exception exception;
|
Exception exception;
|
||||||
|
|
||||||
CompletableResult(AsyncCallback<T> callback) {
|
CompletableResult(AsyncCallback<T> callback) {
|
||||||
this.lock = new Object();
|
this.lock = new Object();
|
||||||
this.callback = Optional.ofNullable(callback);
|
this.callback = Optional.ofNullable(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
void setValue(T value) {
|
void setValue(T value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.state = COMPLETED;
|
this.state = COMPLETED;
|
||||||
this.callback.ifPresent(ac -> ac.onComplete(value, Optional.<Exception>empty()));
|
this.callback.ifPresent(ac -> ac.onComplete(value, Optional.<Exception>empty()));
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
lock.notifyAll();
|
lock.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
void setException(Exception exception) {
|
void setException(Exception exception) {
|
||||||
this.exception = exception;
|
this.exception = exception;
|
||||||
this.state = FAILED;
|
this.state = FAILED;
|
||||||
this.callback.ifPresent(ac -> ac.onComplete(null, Optional.of(exception)));
|
this.callback.ifPresent(ac -> ac.onComplete(null, Optional.of(exception)));
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
lock.notifyAll();
|
lock.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCompleted() {
|
public boolean isCompleted() {
|
||||||
return (state > RUNNING);
|
return (state > RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getValue() throws ExecutionException {
|
public T getValue() throws ExecutionException {
|
||||||
if (state == COMPLETED) {
|
if (state == COMPLETED) {
|
||||||
return value;
|
return value;
|
||||||
} else if (state == FAILED) {
|
} else if (state == FAILED) {
|
||||||
throw new ExecutionException(exception);
|
throw new ExecutionException(exception);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Execution not completed yet");
|
throw new IllegalStateException("Execution not completed yet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void await() throws InterruptedException {
|
public void await() throws InterruptedException {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (!isCompleted()) {
|
if (!isCompleted()) {
|
||||||
lock.wait();
|
lock.wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,9 @@ import org.junit.Test;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
*/
|
||||||
BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(
|
public static void main(String[] args) {
|
||||||
new Excalibur());
|
BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(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();
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,31 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class BlindingMagicWeapon extends MagicWeapon {
|
public class BlindingMagicWeapon extends MagicWeapon {
|
||||||
|
|
||||||
public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
|
public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) {
|
||||||
super(imp);
|
super(imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlindingMagicWeaponImpl getImp() {
|
public BlindingMagicWeaponImpl getImp() {
|
||||||
return (BlindingMagicWeaponImpl) imp;
|
return (BlindingMagicWeaponImpl) imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wield() {
|
public void wield() {
|
||||||
getImp().wieldImp();
|
getImp().wieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swing() {
|
public void swing() {
|
||||||
getImp().swingImp();
|
getImp().swingImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwield() {
|
public void unwield() {
|
||||||
getImp().unwieldImp();
|
getImp().unwieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void blind() {
|
|
||||||
getImp().blindImp();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void blind() {
|
||||||
|
getImp().blindImp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,6 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl {
|
public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl {
|
||||||
|
|
||||||
public abstract void blindImp();
|
public abstract void blindImp();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,23 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class Excalibur extends BlindingMagicWeaponImpl {
|
public class Excalibur extends BlindingMagicWeaponImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wieldImp() {
|
public void wieldImp() {
|
||||||
System.out.println("wielding Excalibur");
|
System.out.println("wielding Excalibur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swingImp() {
|
public void swingImp() {
|
||||||
System.out.println("swinging Excalibur");
|
System.out.println("swinging Excalibur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwieldImp() {
|
public void unwieldImp() {
|
||||||
System.out.println("unwielding Excalibur");
|
System.out.println("unwielding Excalibur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void blindImp() {
|
|
||||||
System.out
|
|
||||||
.println("bright light streams from Excalibur blinding the enemy");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blindImp() {
|
||||||
|
System.out.println("bright light streams from Excalibur blinding the enemy");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,31 +7,31 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class FlyingMagicWeapon extends MagicWeapon {
|
public class FlyingMagicWeapon extends MagicWeapon {
|
||||||
|
|
||||||
public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) {
|
public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) {
|
||||||
super(imp);
|
super(imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FlyingMagicWeaponImpl getImp() {
|
public FlyingMagicWeaponImpl getImp() {
|
||||||
return (FlyingMagicWeaponImpl) imp;
|
return (FlyingMagicWeaponImpl) imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wield() {
|
public void wield() {
|
||||||
getImp().wieldImp();
|
getImp().wieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swing() {
|
public void swing() {
|
||||||
getImp().swingImp();
|
getImp().swingImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwield() {
|
public void unwield() {
|
||||||
getImp().unwieldImp();
|
getImp().unwieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fly() {
|
public void fly() {
|
||||||
getImp().flyImp();
|
getImp().flyImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,6 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public abstract class FlyingMagicWeaponImpl extends MagicWeaponImpl {
|
public abstract class FlyingMagicWeaponImpl extends MagicWeaponImpl {
|
||||||
|
|
||||||
public abstract void flyImp();
|
public abstract void flyImp();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,19 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public abstract class MagicWeapon {
|
public abstract class MagicWeapon {
|
||||||
|
|
||||||
protected MagicWeaponImpl imp;
|
protected MagicWeaponImpl imp;
|
||||||
|
|
||||||
public MagicWeapon(MagicWeaponImpl imp) {
|
public MagicWeapon(MagicWeaponImpl imp) {
|
||||||
this.imp = imp;
|
this.imp = imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void wield();
|
public abstract void wield();
|
||||||
|
|
||||||
public abstract void swing();
|
public abstract void swing();
|
||||||
|
|
||||||
public abstract void unwield();
|
public abstract void unwield();
|
||||||
|
|
||||||
public MagicWeaponImpl getImp() {
|
|
||||||
return imp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public MagicWeaponImpl getImp() {
|
||||||
|
return imp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public abstract class MagicWeaponImpl {
|
public abstract class MagicWeaponImpl {
|
||||||
|
|
||||||
public abstract void wieldImp();
|
public abstract void wieldImp();
|
||||||
|
|
||||||
public abstract void swingImp();
|
public abstract void swingImp();
|
||||||
|
|
||||||
public abstract void unwieldImp();
|
public abstract void unwieldImp();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,23 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class Mjollnir extends FlyingMagicWeaponImpl {
|
public class Mjollnir extends FlyingMagicWeaponImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wieldImp() {
|
public void wieldImp() {
|
||||||
System.out.println("wielding Mjollnir");
|
System.out.println("wielding Mjollnir");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swingImp() {
|
public void swingImp() {
|
||||||
System.out.println("swinging Mjollnir");
|
System.out.println("swinging Mjollnir");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwieldImp() {
|
public void unwieldImp() {
|
||||||
System.out.println("unwielding Mjollnir");
|
System.out.println("unwielding Mjollnir");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flyImp() {
|
|
||||||
System.out
|
|
||||||
.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flyImp() {
|
||||||
|
System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,32 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class SoulEatingMagicWeapon extends MagicWeapon {
|
public class SoulEatingMagicWeapon extends MagicWeapon {
|
||||||
|
|
||||||
public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) {
|
public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) {
|
||||||
super(imp);
|
super(imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SoulEatingMagicWeaponImpl getImp() {
|
public SoulEatingMagicWeaponImpl getImp() {
|
||||||
return (SoulEatingMagicWeaponImpl) imp;
|
return (SoulEatingMagicWeaponImpl) imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wield() {
|
public void wield() {
|
||||||
getImp().wieldImp();
|
getImp().wieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swing() {
|
public void swing() {
|
||||||
getImp().swingImp();
|
getImp().swingImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwield() {
|
public void unwield() {
|
||||||
getImp().unwieldImp();
|
getImp().unwieldImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void eatSoul() {
|
public void eatSoul() {
|
||||||
getImp().eatSoulImp();
|
getImp().eatSoulImp();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,6 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl {
|
public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl {
|
||||||
|
|
||||||
public abstract void eatSoulImp();
|
public abstract void eatSoulImp();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,23 @@ package com.iluwatar.bridge;
|
|||||||
*/
|
*/
|
||||||
public class Stormbringer extends SoulEatingMagicWeaponImpl {
|
public class Stormbringer extends SoulEatingMagicWeaponImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wieldImp() {
|
public void wieldImp() {
|
||||||
System.out.println("wielding Stormbringer");
|
System.out.println("wielding Stormbringer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void swingImp() {
|
public void swingImp() {
|
||||||
System.out.println("swinging Stormbringer");
|
System.out.println("swinging Stormbringer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwieldImp() {
|
public void unwieldImp() {
|
||||||
System.out.println("unwielding Stormbringer");
|
System.out.println("unwielding Stormbringer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eatSoulImp() {
|
|
||||||
System.out.println("Stormbringer devours the enemy's soul");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eatSoulImp() {
|
||||||
|
System.out.println("Stormbringer devours the enemy's soul");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.bridge.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,55 @@
|
|||||||
package com.iluwatar.builder;
|
package com.iluwatar.builder;
|
||||||
|
|
||||||
import com.iluwatar. builder.Hero.HeroBuilder;
|
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)
|
||||||
System.out.println(thief);
|
.withWeapon(Weapon.BOW).build();
|
||||||
|
System.out.println(thief);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,16 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public enum Armor {
|
public enum Armor {
|
||||||
|
|
||||||
CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
|
CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
Armor(String title) {
|
Armor(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public enum HairColor {
|
public enum HairColor {
|
||||||
|
|
||||||
WHITE, BLOND, RED, BROWN, BLACK;
|
WHITE, BLOND, RED, BROWN, BLACK;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name().toLowerCase();
|
return name().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,17 @@ 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;
|
||||||
|
|
||||||
HairType(String title) {
|
HairType(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,123 +7,122 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public class Hero {
|
public class Hero {
|
||||||
|
|
||||||
private final Profession profession;
|
private final Profession profession;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final HairType hairType;
|
private final HairType hairType;
|
||||||
private final HairColor hairColor;
|
private final HairColor hairColor;
|
||||||
private final Armor armor;
|
private final Armor armor;
|
||||||
private final Weapon weapon;
|
private final Weapon weapon;
|
||||||
|
|
||||||
public Profession getProfession() {
|
public Profession getProfession() {
|
||||||
return profession;
|
return profession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HairType getHairType() {
|
public HairType getHairType() {
|
||||||
return hairType;
|
return hairType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HairColor getHairColor() {
|
public HairColor getHairColor() {
|
||||||
return hairColor;
|
return hairColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Armor getArmor() {
|
public Armor getArmor() {
|
||||||
return armor;
|
return armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Weapon getWeapon() {
|
public Weapon getWeapon() {
|
||||||
return weapon;
|
return weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("This is a ");
|
sb.append("This is a ");
|
||||||
sb.append(profession);
|
sb.append(profession);
|
||||||
sb.append(" named ");
|
sb.append(" named ");
|
||||||
sb.append(name);
|
sb.append(name);
|
||||||
if (hairColor != null || hairType != null) {
|
if (hairColor != null || hairType != null) {
|
||||||
sb.append(" with ");
|
sb.append(" with ");
|
||||||
if (hairColor != null) {
|
if (hairColor != null) {
|
||||||
sb.append(hairColor);
|
sb.append(hairColor);
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
if (hairType != null) {
|
if (hairType != null) {
|
||||||
sb.append(hairType);
|
sb.append(hairType);
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(hairType != HairType.BALD ? "hair" : "head");
|
sb.append(hairType != HairType.BALD ? "hair" : "head");
|
||||||
}
|
}
|
||||||
if (armor != null) {
|
if (armor != null) {
|
||||||
sb.append(" wearing ");
|
sb.append(" wearing ");
|
||||||
sb.append(armor);
|
sb.append(armor);
|
||||||
}
|
}
|
||||||
if (weapon != null) {
|
if (weapon != null) {
|
||||||
sb.append(" and wielding a ");
|
sb.append(" and wielding a ");
|
||||||
sb.append(weapon);
|
sb.append(weapon);
|
||||||
}
|
}
|
||||||
sb.append(".");
|
sb.append(".");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Hero(HeroBuilder builder) {
|
private Hero(HeroBuilder builder) {
|
||||||
this.profession = builder.profession;
|
this.profession = builder.profession;
|
||||||
this.name = builder.name;
|
this.name = builder.name;
|
||||||
this.hairColor = builder.hairColor;
|
this.hairColor = builder.hairColor;
|
||||||
this.hairType = builder.hairType;
|
this.hairType = builder.hairType;
|
||||||
this.weapon = builder.weapon;
|
this.weapon = builder.weapon;
|
||||||
this.armor = builder.armor;
|
this.armor = builder.armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The builder class.
|
* The builder class.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static class HeroBuilder {
|
public static class HeroBuilder {
|
||||||
|
|
||||||
private final Profession profession;
|
private final Profession profession;
|
||||||
private final String name;
|
private final String name;
|
||||||
private HairType hairType;
|
private HairType hairType;
|
||||||
private HairColor hairColor;
|
private HairColor hairColor;
|
||||||
private Armor armor;
|
private Armor armor;
|
||||||
private Weapon weapon;
|
private Weapon weapon;
|
||||||
|
|
||||||
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;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public HeroBuilder withHairType(HairType hairType) {
|
public HeroBuilder withHairType(HairType hairType) {
|
||||||
this.hairType = hairType;
|
this.hairType = hairType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeroBuilder withHairColor(HairColor hairColor) {
|
public HeroBuilder withHairColor(HairColor hairColor) {
|
||||||
this.hairColor = hairColor;
|
this.hairColor = hairColor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeroBuilder withArmor(Armor armor) {
|
public HeroBuilder withArmor(Armor armor) {
|
||||||
this.armor = armor;
|
this.armor = armor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeroBuilder withWeapon(Weapon weapon) {
|
public HeroBuilder withWeapon(Weapon weapon) {
|
||||||
this.weapon = weapon;
|
this.weapon = weapon;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hero build() {
|
public Hero build() {
|
||||||
return new Hero(this);
|
return new Hero(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,10 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public enum Profession {
|
public enum Profession {
|
||||||
|
|
||||||
WARRIOR, THIEF, MAGE, PRIEST;
|
WARRIOR, THIEF, MAGE, PRIEST;
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,10 @@ package com.iluwatar.builder;
|
|||||||
*/
|
*/
|
||||||
public enum Weapon {
|
public enum Weapon {
|
||||||
|
|
||||||
DAGGER, SWORD, AXE, WARHAMMER, BOW;
|
DAGGER, SWORD, AXE, WARHAMMER, BOW;
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package com.iluwatar.builder;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.iluwatar. builder.App;
|
import com.iluwatar.builder.App;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -11,9 +11,9 @@ import com.iluwatar. builder.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,34 +2,36 @@ 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
|
|
||||||
* @param args command line args
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
BusinessDelegate businessDelegate = new BusinessDelegate();
|
|
||||||
businessDelegate.setServiceType(ServiceType.EJB);
|
|
||||||
|
|
||||||
Client client = new Client(businessDelegate);
|
/**
|
||||||
client.doTask();
|
* Program entry point
|
||||||
|
*
|
||||||
|
* @param args command line args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
businessDelegate.setServiceType(ServiceType.JMS);
|
BusinessDelegate businessDelegate = new BusinessDelegate();
|
||||||
client.doTask();
|
businessDelegate.setServiceType(ServiceType.EJB);
|
||||||
}
|
|
||||||
|
Client client = new Client(businessDelegate);
|
||||||
|
client.doTask();
|
||||||
|
|
||||||
|
businessDelegate.setServiceType(ServiceType.JMS);
|
||||||
|
client.doTask();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,17 @@ package com.iluwatar.business.delegate;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BusinessDelegate {
|
public class BusinessDelegate {
|
||||||
|
|
||||||
private BusinessLookup lookupService = new BusinessLookup();
|
|
||||||
private BusinessService businessService;
|
|
||||||
private ServiceType serviceType;
|
|
||||||
|
|
||||||
public void setServiceType(ServiceType serviceType) {
|
private BusinessLookup lookupService = new BusinessLookup();
|
||||||
this.serviceType = serviceType;
|
private BusinessService businessService;
|
||||||
}
|
private ServiceType serviceType;
|
||||||
|
|
||||||
public void doTask() {
|
public void setServiceType(ServiceType serviceType) {
|
||||||
businessService = lookupService.getBusinessService(serviceType);
|
this.serviceType = serviceType;
|
||||||
businessService.doProcessing();
|
}
|
||||||
}
|
|
||||||
|
public void doTask() {
|
||||||
|
businessService = lookupService.getBusinessService(serviceType);
|
||||||
|
businessService.doProcessing();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public class BusinessLookup {
|
public class BusinessLookup {
|
||||||
|
|
||||||
public BusinessService getBusinessService(ServiceType serviceType) {
|
public BusinessService getBusinessService(ServiceType serviceType) {
|
||||||
if (serviceType.equals(ServiceType.EJB)) {
|
if (serviceType.equals(ServiceType.EJB)) {
|
||||||
return new EjbService();
|
return new EjbService();
|
||||||
} else {
|
} else {
|
||||||
return new JmsService();
|
return new JmsService();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public interface BusinessService {
|
public interface BusinessService {
|
||||||
|
|
||||||
void doProcessing();
|
void doProcessing();
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public class Client {
|
public class Client {
|
||||||
|
|
||||||
private BusinessDelegate businessDelegate;
|
private BusinessDelegate businessDelegate;
|
||||||
|
|
||||||
public Client(BusinessDelegate businessDelegate) {
|
public Client(BusinessDelegate businessDelegate) {
|
||||||
this.businessDelegate = businessDelegate;
|
this.businessDelegate = businessDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doTask() {
|
public void doTask() {
|
||||||
businessDelegate.doTask();
|
businessDelegate.doTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public class EjbService implements BusinessService {
|
public class EjbService implements BusinessService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
public void doProcessing() {
|
||||||
System.out.println("EjbService is now processing");
|
System.out.println("EjbService is now processing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ package com.iluwatar.business.delegate;
|
|||||||
*/
|
*/
|
||||||
public class JmsService implements BusinessService {
|
public class JmsService implements BusinessService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
public void doProcessing() {
|
||||||
System.out.println("JmsService is now processing");
|
System.out.println("JmsService is now processing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,6 @@ package com.iluwatar.business.delegate;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum ServiceType {
|
public enum ServiceType {
|
||||||
|
|
||||||
EJB, JMS;
|
EJB, JMS;
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import com.iluwatar.business.delegate.App;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,20 +2,21 @@ 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 {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Task task = new SimpleTask();
|
Task task = new SimpleTask();
|
||||||
Callback callback = new Callback() {
|
Callback callback = new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
System.out.println("I'm done now.");
|
System.out.println("I'm done now.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
task.executeWith(callback);
|
task.executeWith(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package com.iluwatar.callback;
|
|||||||
*/
|
*/
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
|
|
||||||
public void call();
|
public void call();
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,8 @@ package com.iluwatar.callback;
|
|||||||
*/
|
*/
|
||||||
public class SimpleTask extends Task {
|
public class SimpleTask extends Task {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@ package com.iluwatar.callback;
|
|||||||
*/
|
*/
|
||||||
public abstract class Task {
|
public abstract class Task {
|
||||||
|
|
||||||
public final void executeWith(Callback callback) {
|
public final void executeWith(Callback callback) {
|
||||||
execute();
|
execute();
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.call();
|
callback.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void execute();
|
public abstract void execute();
|
||||||
}
|
}
|
||||||
|
@ -5,35 +5,35 @@ 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.
|
||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
private Integer callingCount = 0;
|
private Integer callingCount = 0;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
Callback callback = new Callback() {
|
Callback callback = new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
callingCount++;
|
callingCount++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Task task = new SimpleTask();
|
Task task = new SimpleTask();
|
||||||
|
|
||||||
assertEquals("Initial calling count of 0", new Integer(0), callingCount);
|
assertEquals("Initial calling count of 0", new Integer(0), callingCount);
|
||||||
|
|
||||||
task.executeWith(callback);
|
task.executeWith(callback);
|
||||||
|
|
||||||
assertEquals("Callback called once", new Integer(1), callingCount);
|
assertEquals("Callback called once", new Integer(1), callingCount);
|
||||||
|
|
||||||
task.executeWith(callback);
|
task.executeWith(callback);
|
||||||
|
|
||||||
assertEquals("Callback called twice", new Integer(2), callingCount);
|
assertEquals("Callback called twice", new Integer(2), callingCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,31 +2,30 @@ 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"));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,21 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public class OrcCommander extends RequestHandler {
|
public class OrcCommander extends RequestHandler {
|
||||||
|
|
||||||
public OrcCommander(RequestHandler handler) {
|
public OrcCommander(RequestHandler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(Request req) {
|
public void handleRequest(Request req) {
|
||||||
if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
|
if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
|
||||||
printHandling(req);
|
printHandling(req);
|
||||||
} else {
|
} else {
|
||||||
super.handleRequest(req);
|
super.handleRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Orc commander";
|
return "Orc commander";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,18 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public class OrcKing {
|
public class OrcKing {
|
||||||
|
|
||||||
RequestHandler chain;
|
RequestHandler chain;
|
||||||
|
|
||||||
public OrcKing() {
|
public OrcKing() {
|
||||||
buildChain();
|
buildChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildChain() {
|
private void buildChain() {
|
||||||
chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
|
chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makeRequest(Request req) {
|
public void makeRequest(Request req) {
|
||||||
chain.handleRequest(req);
|
chain.handleRequest(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,22 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public class OrcOfficer extends RequestHandler {
|
public class OrcOfficer extends RequestHandler {
|
||||||
|
|
||||||
public OrcOfficer(RequestHandler handler) {
|
public OrcOfficer(RequestHandler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(Request req) {
|
public void handleRequest(Request req) {
|
||||||
if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) {
|
if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) {
|
||||||
printHandling(req);
|
printHandling(req);
|
||||||
} else {
|
} else {
|
||||||
super.handleRequest(req);
|
super.handleRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Orc officer";
|
return "Orc officer";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,21 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public class OrcSoldier extends RequestHandler {
|
public class OrcSoldier extends RequestHandler {
|
||||||
|
|
||||||
public OrcSoldier(RequestHandler handler) {
|
public OrcSoldier(RequestHandler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(Request req) {
|
public void handleRequest(Request req) {
|
||||||
if (req.getRequestType().equals(RequestType.COLLECT_TAX)) {
|
if (req.getRequestType().equals(RequestType.COLLECT_TAX)) {
|
||||||
printHandling(req);
|
printHandling(req);
|
||||||
} else {
|
} else {
|
||||||
super.handleRequest(req);
|
super.handleRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Orc soldier";
|
return "Orc soldier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,32 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public class Request {
|
public class Request {
|
||||||
|
|
||||||
private String requestDescription;
|
private String requestDescription;
|
||||||
private RequestType requestType;
|
private RequestType requestType;
|
||||||
|
|
||||||
public Request(RequestType requestType, String requestDescription) {
|
public Request(RequestType requestType, String requestDescription) {
|
||||||
this.setRequestType(requestType);
|
this.setRequestType(requestType);
|
||||||
this.setRequestDescription(requestDescription);
|
this.setRequestDescription(requestDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRequestDescription() {
|
public String getRequestDescription() {
|
||||||
return requestDescription;
|
return requestDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRequestDescription(String requestDescription) {
|
public void setRequestDescription(String requestDescription) {
|
||||||
this.requestDescription = requestDescription;
|
this.requestDescription = requestDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestType getRequestType() {
|
public RequestType getRequestType() {
|
||||||
return requestType;
|
return requestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRequestType(RequestType requestType) {
|
public void setRequestType(RequestType requestType) {
|
||||||
this.requestType = requestType;
|
this.requestType = requestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getRequestDescription();
|
return getRequestDescription();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,22 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public abstract class RequestHandler {
|
public abstract class RequestHandler {
|
||||||
|
|
||||||
private RequestHandler next;
|
private RequestHandler next;
|
||||||
|
|
||||||
public RequestHandler(RequestHandler next) {
|
public RequestHandler(RequestHandler next) {
|
||||||
this.next = next;
|
this.next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleRequest(Request req) {
|
public void handleRequest(Request req) {
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
next.handleRequest(req);
|
next.handleRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void printHandling(Request req) {
|
protected void printHandling(Request req) {
|
||||||
System.out.println(this + " handling request \"" + req + "\"");
|
System.out.println(this + " handling request \"" + req + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,6 @@ package com.iluwatar.chain;
|
|||||||
*/
|
*/
|
||||||
public enum RequestType {
|
public enum RequestType {
|
||||||
|
|
||||||
DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
|
DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.chain.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,52 +2,54 @@ 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.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
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) {
|
*/
|
||||||
Wizard wizard = new Wizard();
|
public static void main(String[] args) {
|
||||||
Goblin goblin = new Goblin();
|
Wizard wizard = new Wizard();
|
||||||
|
Goblin goblin = new Goblin();
|
||||||
|
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.castSpell(new ShrinkSpell(), goblin);
|
wizard.castSpell(new ShrinkSpell(), goblin);
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.castSpell(new InvisibilitySpell(), goblin);
|
wizard.castSpell(new InvisibilitySpell(), goblin);
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.undoLastSpell();
|
wizard.undoLastSpell();
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.undoLastSpell();
|
wizard.undoLastSpell();
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.redoLastSpell();
|
wizard.redoLastSpell();
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
|
|
||||||
wizard.redoLastSpell();
|
wizard.redoLastSpell();
|
||||||
goblin.printStatus();
|
goblin.printStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public abstract class Command {
|
public abstract class Command {
|
||||||
|
|
||||||
public abstract void execute(Target target);
|
public abstract void execute(Target target);
|
||||||
|
|
||||||
public abstract void undo();
|
public abstract void undo();
|
||||||
|
|
||||||
public abstract void redo();
|
public abstract void redo();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,14 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public class Goblin extends Target {
|
public class Goblin extends Target {
|
||||||
|
|
||||||
public Goblin() {
|
public Goblin() {
|
||||||
setSize(Size.NORMAL);
|
setSize(Size.NORMAL);
|
||||||
setVisibility(Visibility.VISIBLE);
|
setVisibility(Visibility.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Goblin";
|
return "Goblin";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,30 +7,30 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public class InvisibilitySpell extends Command {
|
public class InvisibilitySpell extends Command {
|
||||||
|
|
||||||
private Target target;
|
private Target target;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Target target) {
|
public void execute(Target target) {
|
||||||
target.setVisibility(Visibility.INVISIBLE);
|
target.setVisibility(Visibility.INVISIBLE);
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void undo() {
|
public void undo() {
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
target.setVisibility(Visibility.VISIBLE);
|
target.setVisibility(Visibility.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void redo() {
|
public void redo() {
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
target.setVisibility(Visibility.INVISIBLE);
|
target.setVisibility(Visibility.INVISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Invisibility spell";
|
return "Invisibility spell";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,32 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public class ShrinkSpell extends Command {
|
public class ShrinkSpell extends Command {
|
||||||
|
|
||||||
private Size oldSize;
|
private Size oldSize;
|
||||||
private Target target;
|
private Target target;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Target target) {
|
public void execute(Target target) {
|
||||||
oldSize = target.getSize();
|
oldSize = target.getSize();
|
||||||
target.setSize(Size.SMALL);
|
target.setSize(Size.SMALL);
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void undo() {
|
public void undo() {
|
||||||
if (oldSize != null && target != null) {
|
if (oldSize != null && target != null) {
|
||||||
Size temp = target.getSize();
|
Size temp = target.getSize();
|
||||||
target.setSize(oldSize);
|
target.setSize(oldSize);
|
||||||
oldSize = temp;
|
oldSize = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void redo() {
|
public void redo() {
|
||||||
undo();
|
undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Shrink spell";
|
return "Shrink spell";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,16 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public enum Size {
|
public enum Size {
|
||||||
|
|
||||||
SMALL("small"), NORMAL("normal"), LARGE("large"), UNDEFINED("");
|
SMALL("small"), NORMAL("normal"), LARGE("large"), UNDEFINED("");
|
||||||
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
Size(String title) {
|
private String title;
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
Size(String title) {
|
||||||
public String toString() {
|
this.title = title;
|
||||||
return title;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,32 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public abstract class Target {
|
public abstract class Target {
|
||||||
|
|
||||||
private Size size;
|
private Size size;
|
||||||
|
|
||||||
private Visibility visibility;
|
private Visibility visibility;
|
||||||
|
|
||||||
public Size getSize() {
|
public Size getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(Size size) {
|
public void setSize(Size size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Visibility getVisibility() {
|
public Visibility getVisibility() {
|
||||||
return visibility;
|
return visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVisibility(Visibility visibility) {
|
public void setVisibility(Visibility visibility) {
|
||||||
this.visibility = visibility;
|
this.visibility = visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,16 @@ package com.iluwatar.command;
|
|||||||
*/
|
*/
|
||||||
public enum Visibility {
|
public enum Visibility {
|
||||||
|
|
||||||
VISIBLE("visible"), INVISIBLE("invisible"), UNDEFINED("");
|
VISIBLE("visible"), INVISIBLE("invisible"), UNDEFINED("");
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
Visibility(String title) {
|
Visibility(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,38 +10,37 @@ import java.util.LinkedList;
|
|||||||
*/
|
*/
|
||||||
public class Wizard {
|
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);
|
||||||
command.execute(target);
|
command.execute(target);
|
||||||
undoStack.offerLast(command);
|
undoStack.offerLast(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undoLastSpell() {
|
public void undoLastSpell() {
|
||||||
if (!undoStack.isEmpty()) {
|
if (!undoStack.isEmpty()) {
|
||||||
Command previousSpell = undoStack.pollLast();
|
Command previousSpell = undoStack.pollLast();
|
||||||
redoStack.offerLast(previousSpell);
|
redoStack.offerLast(previousSpell);
|
||||||
System.out.println(this + " undoes " + previousSpell);
|
System.out.println(this + " undoes " + previousSpell);
|
||||||
previousSpell.undo();
|
previousSpell.undo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redoLastSpell() {
|
public void redoLastSpell() {
|
||||||
if (!redoStack.isEmpty()) {
|
if (!redoStack.isEmpty()) {
|
||||||
Command previousSpell = redoStack.pollLast();
|
Command previousSpell = redoStack.pollLast();
|
||||||
undoStack.offerLast(previousSpell);
|
undoStack.offerLast(previousSpell);
|
||||||
System.out.println(this + " redoes " + previousSpell);
|
System.out.println(this + " redoes " + previousSpell);
|
||||||
previousSpell.redo();
|
previousSpell.redo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Wizard";
|
return "Wizard";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.command.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,34 @@
|
|||||||
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) {
|
*/
|
||||||
System.out.println("Message from the orcs: ");
|
public static void main(String[] args) {
|
||||||
|
System.out.println("Message from the orcs: ");
|
||||||
|
|
||||||
LetterComposite orcMessage = new Messenger().messageFromOrcs();
|
LetterComposite orcMessage = new Messenger().messageFromOrcs();
|
||||||
orcMessage.print();
|
orcMessage.print();
|
||||||
|
|
||||||
System.out.println("\n");
|
System.out.println("\n");
|
||||||
|
|
||||||
System.out.println("Message from the elves: ");
|
System.out.println("Message from the elves: ");
|
||||||
|
|
||||||
LetterComposite elfMessage = new Messenger().messageFromElves();
|
LetterComposite elfMessage = new Messenger().messageFromElves();
|
||||||
elfMessage.print();
|
elfMessage.print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,19 @@ package com.iluwatar.composite;
|
|||||||
*/
|
*/
|
||||||
public class Letter extends LetterComposite {
|
public class Letter extends LetterComposite {
|
||||||
|
|
||||||
private char c;
|
private char c;
|
||||||
|
|
||||||
public Letter(char c) {
|
public Letter(char c) {
|
||||||
this.c = c;
|
this.c = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printThisBefore() {
|
protected void printThisBefore() {
|
||||||
System.out.print(c);
|
System.out.print(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void printThisAfter() {
|
|
||||||
// nop
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void printThisAfter() {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,25 +10,25 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class LetterComposite {
|
public abstract class LetterComposite {
|
||||||
|
|
||||||
private List<LetterComposite> children = new ArrayList<LetterComposite>();
|
private List<LetterComposite> children = new ArrayList<LetterComposite>();
|
||||||
|
|
||||||
public void add(LetterComposite letter) {
|
public void add(LetterComposite letter) {
|
||||||
children.add(letter);
|
children.add(letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int count() {
|
public int count() {
|
||||||
return children.size();
|
return children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void printThisBefore();
|
protected abstract void printThisBefore();
|
||||||
|
|
||||||
protected abstract void printThisAfter();
|
protected abstract void printThisAfter();
|
||||||
|
|
||||||
public void print() {
|
public void print() {
|
||||||
printThisBefore();
|
printThisBefore();
|
||||||
for (LetterComposite letter : children) {
|
for (LetterComposite letter : children) {
|
||||||
letter.print();
|
letter.print();
|
||||||
}
|
}
|
||||||
printThisAfter();
|
printThisAfter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,48 +11,47 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Messenger {
|
public class Messenger {
|
||||||
|
|
||||||
LetterComposite messageFromOrcs() {
|
LetterComposite messageFromOrcs() {
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LetterComposite messageFromElves() {
|
LetterComposite messageFromElves() {
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,19 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Sentence extends LetterComposite {
|
public class Sentence extends LetterComposite {
|
||||||
|
|
||||||
public Sentence(List<Word> words) {
|
public Sentence(List<Word> words) {
|
||||||
for (Word w : words) {
|
for (Word w : words) {
|
||||||
this.add(w);
|
this.add(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printThisBefore() {
|
protected void printThisBefore() {
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void printThisAfter() {
|
|
||||||
System.out.print(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void printThisAfter() {
|
||||||
|
System.out.print(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,19 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Word extends LetterComposite {
|
public class Word extends LetterComposite {
|
||||||
|
|
||||||
public Word(List<Letter> letters) {
|
public Word(List<Letter> letters) {
|
||||||
for (Letter l : letters) {
|
for (Letter l : letters) {
|
||||||
this.add(l);
|
this.add(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printThisBefore() {
|
protected void printThisBefore() {
|
||||||
System.out.print(" ");
|
System.out.print(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void printThisAfter() {
|
|
||||||
// nop
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void printThisAfter() {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.composite.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,53 +7,55 @@ 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 {
|
||||||
|
|
||||||
private static Logger LOGGER = Logger.getLogger(App.class);
|
private static Logger LOGGER = Logger.getLogger(App.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args.
|
* @param args command line args.
|
||||||
*/
|
*/
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
final CustomerDaoImpl customerDao = new CustomerDaoImpl(generateSampleCustomers());
|
final CustomerDaoImpl customerDao = new CustomerDaoImpl(generateSampleCustomers());
|
||||||
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
||||||
LOGGER.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2));
|
LOGGER.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2));
|
||||||
final Customer customer = new Customer(4, "Dan", "Danson");
|
final Customer customer = new Customer(4, "Dan", "Danson");
|
||||||
customerDao.addCustomer(customer);
|
customerDao.addCustomer(customer);
|
||||||
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
||||||
customer.setFirstName("Daniel");
|
customer.setFirstName("Daniel");
|
||||||
customer.setLastName("Danielson");
|
customer.setLastName("Danielson");
|
||||||
customerDao.updateCustomer(customer);
|
customerDao.updateCustomer(customer);
|
||||||
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
||||||
customerDao.deleteCustomer(customer);
|
customerDao.deleteCustomer(customer);
|
||||||
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate customers.
|
* Generate customers.
|
||||||
*
|
*
|
||||||
* @return list of customers.
|
* @return list of customers.
|
||||||
*/
|
*/
|
||||||
public static List<Customer> generateSampleCustomers() {
|
public static List<Customer> generateSampleCustomers() {
|
||||||
final Customer customer1 = new Customer(1, "Adam", "Adamson");
|
final Customer customer1 = new Customer(1, "Adam", "Adamson");
|
||||||
final Customer customer2 = new Customer(2, "Bob", "Bobson");
|
final Customer customer2 = new Customer(2, "Bob", "Bobson");
|
||||||
final Customer customer3 = new Customer(3, "Carl", "Carlson");
|
final Customer customer3 = new Customer(3, "Carl", "Carlson");
|
||||||
final List<Customer> customers = new ArrayList<Customer>();
|
final List<Customer> customers = new ArrayList<Customer>();
|
||||||
customers.add(customer1);
|
customers.add(customer1);
|
||||||
customers.add(customer2);
|
customers.add(customer2);
|
||||||
customers.add(customer3);
|
customers.add(customer3);
|
||||||
return customers;
|
return customers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,37 +2,37 @@ 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) {
|
||||||
|
|
||||||
// simple troll
|
// simple troll
|
||||||
System.out.println("A simple looking troll approaches.");
|
System.out.println("A simple looking troll approaches.");
|
||||||
Hostile troll = new Troll();
|
Hostile troll = new Troll();
|
||||||
troll.attack();
|
troll.attack();
|
||||||
troll.fleeBattle();
|
troll.fleeBattle();
|
||||||
System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
|
System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
|
||||||
|
|
||||||
// change the behavior of the simple troll by adding a decorator
|
// change the behavior of the simple troll by adding a decorator
|
||||||
System.out.println("\nA smart looking troll surprises you.");
|
System.out.println("\nA smart looking troll surprises you.");
|
||||||
Hostile smart = new SmartTroll(troll);
|
Hostile smart = new SmartTroll(troll);
|
||||||
smart.attack();
|
smart.attack();
|
||||||
smart.fleeBattle();
|
smart.fleeBattle();
|
||||||
System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
|
System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ package com.iluwatar.decorator;
|
|||||||
*/
|
*/
|
||||||
public interface Hostile {
|
public interface Hostile {
|
||||||
|
|
||||||
void attack();
|
void attack();
|
||||||
|
|
||||||
int getAttackPower();
|
int getAttackPower();
|
||||||
|
|
||||||
void fleeBattle();
|
void fleeBattle();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,34 @@
|
|||||||
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 {
|
||||||
|
|
||||||
private Hostile decorated;
|
private Hostile decorated;
|
||||||
|
|
||||||
public SmartTroll(Hostile decorated) {
|
public SmartTroll(Hostile decorated) {
|
||||||
this.decorated = decorated;
|
this.decorated = decorated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attack() {
|
public void attack() {
|
||||||
System.out.println("The troll throws a rock at you!");
|
System.out.println("The troll throws a rock at you!");
|
||||||
decorated.attack();
|
decorated.attack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPower() {
|
public int getAttackPower() {
|
||||||
// decorated troll power + 20 because it is smart
|
// decorated troll power + 20 because it is smart
|
||||||
return decorated.getAttackPower() + 20;
|
return decorated.getAttackPower() + 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fleeBattle() {
|
|
||||||
System.out.println("The troll calls for help!");
|
|
||||||
decorated.fleeBattle();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fleeBattle() {
|
||||||
|
System.out.println("The troll calls for help!");
|
||||||
|
decorated.fleeBattle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,16 @@ package com.iluwatar.decorator;
|
|||||||
*/
|
*/
|
||||||
public class Troll implements Hostile {
|
public class Troll implements Hostile {
|
||||||
|
|
||||||
public void attack() {
|
public void attack() {
|
||||||
System.out.println("The troll swings at you with a club!");
|
System.out.println("The troll swings at you with a club!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPower() {
|
public int getAttackPower() {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fleeBattle() {
|
|
||||||
System.out.println("The troll shrieks in horror and runs away!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void fleeBattle() {
|
||||||
|
System.out.println("The troll shrieks in horror and runs away!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.iluwatar.decorator.App;
|
|||||||
*/
|
*/
|
||||||
public class AppTest {
|
public class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,20 @@ 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 {
|
||||||
|
|
||||||
private Tobacco tobacco;
|
|
||||||
|
|
||||||
public AdvancedWizard(Tobacco tobacco) {
|
private Tobacco tobacco;
|
||||||
this.tobacco = tobacco;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public AdvancedWizard(Tobacco tobacco) {
|
||||||
public void smoke() {
|
this.tobacco = tobacco;
|
||||||
tobacco.smoke(this);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void smoke() {
|
||||||
|
tobacco.smoke(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,40 +5,41 @@ import com.google.inject.Injector;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Dependency Injection pattern deals with how objects handle their dependencies. The pattern
|
* Dependency Injection pattern deals with how objects handle their dependencies. The pattern
|
||||||
* implements so called inversion of control principle. Inversion of control has two specific rules:
|
* implements so called inversion of control principle. Inversion of control has two specific rules:
|
||||||
* - 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 ) {
|
*/
|
||||||
SimpleWizard simpleWizard = new SimpleWizard();
|
public static void main(String[] args) {
|
||||||
simpleWizard.smoke();
|
SimpleWizard simpleWizard = new SimpleWizard();
|
||||||
|
simpleWizard.smoke();
|
||||||
AdvancedWizard advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
|
|
||||||
advancedWizard.smoke();
|
AdvancedWizard advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
|
||||||
|
advancedWizard.smoke();
|
||||||
Injector injector = Guice.createInjector(new TobaccoModule());
|
|
||||||
GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class);
|
Injector injector = Guice.createInjector(new TobaccoModule());
|
||||||
guiceWizard.smoke();
|
GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class);
|
||||||
}
|
guiceWizard.smoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,21 @@ 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 {
|
||||||
|
|
||||||
private Tobacco tobacco;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public GuiceWizard(Tobacco tobacco) {
|
|
||||||
this.tobacco = tobacco;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private Tobacco tobacco;
|
||||||
public void smoke() {
|
|
||||||
tobacco.smoke(this);
|
@Inject
|
||||||
}
|
public GuiceWizard(Tobacco tobacco) {
|
||||||
|
this.tobacco = tobacco;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void smoke() {
|
||||||
|
tobacco.smoke(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,15 @@ 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 {
|
||||||
|
|
||||||
private OldTobyTobacco tobacco = new OldTobyTobacco();
|
private OldTobyTobacco tobacco = new OldTobyTobacco();
|
||||||
|
|
||||||
public void smoke() {
|
public void smoke() {
|
||||||
tobacco.smoke(this);
|
tobacco.smoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@ 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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ import com.google.inject.AbstractModule;
|
|||||||
*/
|
*/
|
||||||
public class TobaccoModule extends AbstractModule {
|
public class TobaccoModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(Tobacco.class).to(RivendellTobacco.class);
|
bind(Tobacco.class).to(RivendellTobacco.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ package com.iluwatar.dependency.injection;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface Wizard {
|
public interface Wizard {
|
||||||
|
|
||||||
void smoke();
|
void smoke();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user