Update factory method

This commit is contained in:
Ilkka Seppälä
2021-06-13 18:35:13 +03:00
parent 588b106ada
commit 6feca5bd01
6 changed files with 41 additions and 39 deletions

View File

@ -21,7 +21,7 @@ Factory Method lets a class defer instantiation to subclasses.
## Explanation ## Explanation
Real world example Real-world example
> Blacksmith manufactures weapons. Elves require Elvish weapons and orcs require Orcish weapons. > Blacksmith manufactures weapons. Elves require Elvish weapons and orcs require Orcish weapons.
> Depending on the customer at hand the right type of blacksmith is summoned. > Depending on the customer at hand the right type of blacksmith is summoned.
@ -40,7 +40,7 @@ Wikipedia says
**Programmatic Example** **Programmatic Example**
Taking our blacksmith example above. First of all we have a `Blacksmith` interface and some Taking our blacksmith example above. First of all, we have a `Blacksmith` interface and some
implementations for it: implementations for it:
```java ```java
@ -65,15 +65,25 @@ When the customers come, the correct type of blacksmith is summoned and requeste
manufactured: manufactured:
```java ```java
var blacksmith = new ElfBlacksmith(); Blacksmith blacksmith = new OrcBlacksmith();
blacksmith.manufactureWeapon(WeaponType.SPEAR); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
blacksmith.manufactureWeapon(WeaponType.AXE); LOGGER.info("{} manufactured {}", blacksmith, weapon);
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
blacksmith = new ElfBlacksmith();
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
``` ```
Program output: Program output:
```java ```
// Elven spear The orc blacksmith manufactured an orcish spear
// Elven axe The orc blacksmith manufactured an orcish axe
The elf blacksmith manufactured an elven spear
The elf blacksmith manufactured an elven axe
``` ```
## Class diagram ## Class diagram
@ -89,7 +99,7 @@ Use the Factory Method pattern when:
* Classes delegate responsibility to one of several helper subclasses, and you want to localize the * Classes delegate responsibility to one of several helper subclasses, and you want to localize the
knowledge of which helper subclass is the delegate. knowledge of which helper subclass is the delegate.
## Real world examples ## Known uses
* [java.util.Calendar](http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance--) * [java.util.Calendar](http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance--)
* [java.util.ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-) * [java.util.ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-)

View File

@ -26,7 +26,7 @@ package com.iluwatar.factory.method;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* The Factory Method is a creational design pattern which uses factory methods to deal with the * The Factory Method is a creational design pattern that uses factory methods to deal with the
* problem of creating objects without specifying the exact class of object that will be created. * problem of creating objects without specifying the exact class of object that will be created.
* This is done by creating objects via calling a factory method either specified in an interface * This is done by creating objects via calling a factory method either specified in an interface
* and implemented by child classes, or implemented in a base class and optionally overridden by * and implemented by child classes, or implemented in a base class and optionally overridden by
@ -41,39 +41,22 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class App { public class App {
private final Blacksmith blacksmith;
/**
* Creates an instance of <code>App</code> which will use <code>blacksmith</code> to manufacture
* the weapons for war.
* <code>App</code> is unaware which concrete implementation of {@link Blacksmith} it is using.
* The decision of which blacksmith implementation to use may depend on configuration, or
* the type of rival in war.
* @param blacksmith a non-null implementation of blacksmith
*/
public App(Blacksmith blacksmith) {
this.blacksmith = blacksmith;
}
/** /**
* 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) {
// Lets go to war with Orc weapons
var app = new App(new OrcBlacksmith());
app.manufactureWeapons();
// Lets go to war with Elf weapons Blacksmith blacksmith = new OrcBlacksmith();
app = new App(new ElfBlacksmith()); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
app.manufactureWeapons(); LOGGER.info("{} manufactured {}", blacksmith, weapon);
}
private void manufactureWeapons() {
var weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info(weapon.toString());
weapon = blacksmith.manufactureWeapon(WeaponType.AXE); weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info(weapon.toString()); LOGGER.info("{} manufactured {}", blacksmith, weapon);
blacksmith = new ElfBlacksmith();
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
} }
} }

View File

@ -44,4 +44,8 @@ public class ElfBlacksmith implements Blacksmith {
return ELFARSENAL.get(weaponType); return ELFARSENAL.get(weaponType);
} }
@Override
public String toString() {
return "The elf blacksmith";
}
} }

View File

@ -37,6 +37,6 @@ public class ElfWeapon implements Weapon {
@Override @Override
public String toString() { public String toString() {
return "Elven " + weaponType; return "an elven " + weaponType;
} }
} }

View File

@ -43,4 +43,9 @@ public class OrcBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) { public Weapon manufactureWeapon(WeaponType weaponType) {
return ORCARSENAL.get(weaponType); return ORCARSENAL.get(weaponType);
} }
@Override
public String toString() {
return "The orc blacksmith";
}
} }

View File

@ -37,6 +37,6 @@ public class OrcWeapon implements Weapon {
@Override @Override
public String toString() { public String toString() {
return "Orcish " + weaponType; return "an orcish " + weaponType;
} }
} }