Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update factory method
  • Loading branch information
iluwatar committed Jun 13, 2021
commit 6feca5bd0111c138402c2745f8bbb42950a60acc
28 changes: 19 additions & 9 deletions factory-method/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Factory Method lets a class defer instantiation to subclasses.

## Explanation

Real world example
Real-world example

> 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.
Expand All @@ -40,7 +40,7 @@ Wikipedia says

**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:

```java
Expand All @@ -65,15 +65,25 @@ When the customers come, the correct type of blacksmith is summoned and requeste
manufactured:

```java
var blacksmith = new ElfBlacksmith();
blacksmith.manufactureWeapon(WeaponType.SPEAR);
blacksmith.manufactureWeapon(WeaponType.AXE);
Blacksmith blacksmith = new OrcBlacksmith();
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
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:
```java
// Elven spear
// Elven axe
```
The orc blacksmith manufactured an orcish spear
The orc blacksmith manufactured an orcish axe
The elf blacksmith manufactured an elven spear
The elf blacksmith manufactured an elven axe
```

## Class diagram
Expand All @@ -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
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.ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-)
Expand Down
37 changes: 10 additions & 27 deletions factory-method/src/main/java/com/iluwatar/factory/method/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
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.
* 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
Expand All @@ -41,39 +41,22 @@
@Slf4j
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.
*
* @param args command line 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
app = new App(new ElfBlacksmith());
app.manufactureWeapons();
}
Blacksmith blacksmith = new OrcBlacksmith();
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info("{} manufactured {}", blacksmith, weapon);

private void manufactureWeapons() {
var weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info(weapon.toString());
blacksmith = new ElfBlacksmith();
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info("{} manufactured {}", blacksmith, weapon);
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info(weapon.toString());
LOGGER.info("{} manufactured {}", blacksmith, weapon);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ public Weapon manufactureWeapon(WeaponType weaponType) {
return ELFARSENAL.get(weaponType);
}

@Override
public String toString() {
return "The elf blacksmith";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ public class ElfWeapon implements Weapon {

@Override
public String toString() {
return "Elven " + weaponType;
return "an elven " + weaponType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ public class OrcBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return ORCARSENAL.get(weaponType);
}

@Override
public String toString() {
return "The orc blacksmith";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ public class OrcWeapon implements Weapon {

@Override
public String toString() {
return "Orcish " + weaponType;
return "an orcish " + weaponType;
}
}