From a251032768716aaf1206f650d1fba7ffb23a27ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 19 Apr 2024 21:30:36 +0300 Subject: [PATCH] docs: update factory method --- factory-method/README.md | 54 +++++++++++-------- .../iluwatar/factory/method/ElfWeapon.java | 6 +-- .../iluwatar/factory/method/OrcWeapon.java | 6 +-- .../com/iluwatar/factory/method/Weapon.java | 2 +- .../factory/method/FactoryMethodTest.java | 2 +- factory/README.md | 4 -- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/factory-method/README.md b/factory-method/README.md index f6819617c..4359969de 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -3,8 +3,11 @@ title: Factory Method category: Creational language: en tag: - - Extensibility - - Gang of Four + - Encapsulation + - Gang of Four + - Instantiation + - Object composition + - Polymorphism --- ## Also known as @@ -13,15 +16,13 @@ Virtual Constructor ## Intent -Define an interface for creating an object, but let subclasses decide which class to instantiate. -Factory Method lets a class defer instantiation to subclasses. +Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. ## Explanation 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. +> 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. In plain words @@ -29,16 +30,11 @@ In plain words Wikipedia says -> In class-based programming, the factory method pattern is a creational pattern that uses factory -> methods to deal with the problem of creating objects without having to specify the exact class of -> the object that will be created. This is done by creating objects by calling a factory method -> — either specified in an interface and implemented by child classes, or implemented in a base -> class and optionally overridden by derived classes—rather than by calling a constructor. +> In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method — either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. - **Programmatic Example** +**Programmatic Example** -Taking our blacksmith example above. First of all, we have a `Blacksmith` interface and some -implementations for it: +Taking our blacksmith example above. First of all, we have a `Blacksmith` interface and some implementations for it: ```java public interface Blacksmith { @@ -58,8 +54,7 @@ public class OrcBlacksmith implements Blacksmith { } ``` -When the customers come, the correct type of blacksmith is summoned and requested weapons are -manufactured: +When the customers come, the correct type of blacksmith is summoned and requested weapons are manufactured: ```java Blacksmith blacksmith = new OrcBlacksmith(); @@ -93,8 +88,7 @@ Use the Factory Method pattern when: * Class cannot anticipate the class of objects it must create. * Class wants its subclasses to specify the objects it creates. -* Classes delegate responsibility to one of several helper subclasses, and you want to localize the -knowledge of which helper subclass is the delegate. +* Classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate. ## Known uses @@ -105,9 +99,27 @@ knowledge of which helper subclass is the delegate. * [java.net.URLStreamHandlerFactory](http://docs.oracle.com/javase/8/docs/api/java/net/URLStreamHandlerFactory.html#createURLStreamHandler-java.lang.String-) * [java.util.EnumSet](https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html#of-E-) * [javax.xml.bind.JAXBContext](https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXBContext.html#createMarshaller--) +* Frameworks that run application components, configured dynamically at runtime. + +## Consequences + +Benefits: + +* Provides hooks for subclasses, creating flexibility in code. +* Connects parallel class hierarchies. +* Eliminates the need to bind application-specific classes into the code. The code only deals with the product interface; hence it can work with any user-defined concrete product classes. + +Trade-offs: + +* Can complicate the code by requiring the addition of new subclasses to implement the extended factory methods. + +## Related Patterns + +* [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/): Factory methods are often called within Abstract Factory patterns. +* [Prototype](https://java-design-patterns.com/patterns/prototype/): A factory method that returns a new instance of a class that is a clone of a prototype class. ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) -* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) -* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0Rk5y) +* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/3UpTLrG) +* [Patterns of Enterprise Application Architecture](https://amzn.to/4b2ZxoM) diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java index b076650ee..e055132e2 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java @@ -30,11 +30,7 @@ import lombok.RequiredArgsConstructor; /** * ElfWeapon. */ -@RequiredArgsConstructor -@Getter -public class ElfWeapon implements Weapon { - - private final WeaponType weaponType; +public record ElfWeapon(WeaponType weaponType) implements Weapon { @Override public String toString() { diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java index 901e20288..8446b9099 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java @@ -30,11 +30,7 @@ import lombok.RequiredArgsConstructor; /** * OrcWeapon. */ -@RequiredArgsConstructor -@Getter -public class OrcWeapon implements Weapon { - - private final WeaponType weaponType; +public record OrcWeapon(WeaponType weaponType) implements Weapon { @Override public String toString() { diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/Weapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/Weapon.java index 37c528bed..97f8cb1d7 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/Weapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/Weapon.java @@ -29,6 +29,6 @@ package com.iluwatar.factory.method; */ public interface Weapon { - WeaponType getWeaponType(); + WeaponType weaponType(); } diff --git a/factory-method/src/test/java/com/iluwatar/factory/method/FactoryMethodTest.java b/factory-method/src/test/java/com/iluwatar/factory/method/FactoryMethodTest.java index 9aa89d455..25b15836e 100644 --- a/factory-method/src/test/java/com/iluwatar/factory/method/FactoryMethodTest.java +++ b/factory-method/src/test/java/com/iluwatar/factory/method/FactoryMethodTest.java @@ -98,6 +98,6 @@ class FactoryMethodTest { private void verifyWeapon(Weapon weapon, WeaponType expectedWeaponType, Class clazz) { assertTrue(clazz.isInstance(weapon), "Weapon must be an object of: " + clazz.getName()); assertEquals(expectedWeaponType, weapon - .getWeaponType(), "Weapon must be of weaponType: " + expectedWeaponType); + .weaponType(), "Weapon must be of weaponType: " + expectedWeaponType); } } diff --git a/factory/README.md b/factory/README.md index ed7fde4c0..7ee6feffa 100644 --- a/factory/README.md +++ b/factory/README.md @@ -7,10 +7,6 @@ tag: - Instantiation --- -## Also known as - -* Factory Method - ## Intent The Factory design pattern is intended to define an interface for creating an object, but allows subclasses to alter the type of objects that will be created. This pattern is particularly useful when the creation process involves complexity.