Compare commits
	
		
			2 Commits
		
	
	
		
			master
			...
			abstract-f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | b10b9c159e | ||
|  | 0aaa5dab01 | 
| @@ -20,9 +20,9 @@ objects without specifying their concrete classes. | |||||||
|  |  | ||||||
| ## Explanation | ## Explanation | ||||||
|  |  | ||||||
| Real world example | Real-world example | ||||||
|  |  | ||||||
| > To create a kingdom we need objects with a common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. | > To create a kingdom we need objects with a common theme. The elven kingdom needs an elven king, elven castle, and elven army whereas the orcish kingdom needs an orcish king, orcish castle, and orcish army. There is a dependency between the objects in the kingdom. | ||||||
|  |  | ||||||
| In plain words | In plain words | ||||||
|  |  | ||||||
| @@ -34,7 +34,7 @@ Wikipedia says | |||||||
|  |  | ||||||
| **Programmatic Example** | **Programmatic Example** | ||||||
|  |  | ||||||
| Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the  | Translating the kingdom example above. First of all, we have some interfaces and implementation for the objects in the  | ||||||
| kingdom. | kingdom. | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| @@ -52,21 +52,21 @@ public interface Army { | |||||||
|  |  | ||||||
| // Elven implementations -> | // Elven implementations -> | ||||||
| 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; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 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; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 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; | ||||||
| @@ -77,7 +77,7 @@ public class ElfArmy implements Army { | |||||||
|  |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Then we have the abstraction and implementations for the kingdom factory | Then we have the abstraction and implementations for the kingdom factory. | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| public interface KingdomFactory { | public interface KingdomFactory { | ||||||
| @@ -111,7 +111,7 @@ public class OrcKingdomFactory implements KingdomFactory { | |||||||
| } | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc. | Now we have the abstract factory that lets us make a family of related objects i.e. elven kingdom factory creates elven castle, king and army, etc. | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| var factory = new ElfKingdomFactory(); | var factory = new ElfKingdomFactory(); | ||||||
| @@ -127,13 +127,13 @@ army.getDescription(); | |||||||
| Program output: | Program output: | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| This is the Elven castle! | This is the elven castle! | ||||||
| This is the Elven king! | This is the elven king! | ||||||
| This is the Elven Army! | This is the elven Army! | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory.   | Now, we can design a factory for our different kingdom factories. In this example, we created `FactoryMaker`, responsible for returning an instance of either `ElfKingdomFactory` or `OrcKingdomFactory`.   | ||||||
| The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle).   | The client can use `FactoryMaker` to create the desired concrete factory which, in turn, will produce different concrete objects (derived from `Army`, `King`, `Castle`).   | ||||||
| In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for. | In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for. | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| @@ -179,8 +179,8 @@ public static void main(String[] args) { | |||||||
|  |  | ||||||
| Use the Abstract Factory pattern when | Use the Abstract Factory pattern when | ||||||
|  |  | ||||||
| * The system should be independent of how its products are created, composed and represented | * The system should be independent of how its products are created, composed, and represented | ||||||
| * The system should be configured with one of multiple families of products | * The system should be configured with one of the multiple families of products | ||||||
| * The family of related product objects is designed to be used together, and you need to enforce this constraint | * The family of related product objects is designed to be used together, and you need to enforce this constraint | ||||||
| * You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations | * You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations | ||||||
| * The lifetime of the dependency is conceptually shorter than the lifetime of the consumer. | * The lifetime of the dependency is conceptually shorter than the lifetime of the consumer. | ||||||
| @@ -200,7 +200,7 @@ Example use cases | |||||||
|  |  | ||||||
| * Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. | * Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. | ||||||
| * While the pattern is great when creating predefined objects, adding the new ones might be challenging. | * While the pattern is great when creating predefined objects, adding the new ones might be challenging. | ||||||
| * The code becomes more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. | * The code becomes more complicated than it should be since a lot of new interfaces and classes are introduced along with the pattern. | ||||||
|  |  | ||||||
| ## Tutorial | ## Tutorial | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ import lombok.extern.slf4j.Slf4j; | |||||||
|  * |  * | ||||||
|  * <p>The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) |  * <p>The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) | ||||||
|  * and its implementations ( {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses |  * and its implementations ( {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses | ||||||
|  * both concrete implementations to create a king, a castle and an army. |  * both concrete implementations to create a king, a castle, and an army. | ||||||
|  */ |  */ | ||||||
| @Slf4j | @Slf4j | ||||||
| public class App implements Runnable { | public class App implements Runnable { | ||||||
| @@ -60,13 +60,13 @@ public class App implements Runnable { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void run() { |   public void run() { | ||||||
|     LOGGER.info("Elf Kingdom"); |     LOGGER.info("elf kingdom"); | ||||||
|     createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |     createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); | ||||||
|     LOGGER.info(kingdom.getArmy().getDescription()); |     LOGGER.info(kingdom.getArmy().getDescription()); | ||||||
|     LOGGER.info(kingdom.getCastle().getDescription()); |     LOGGER.info(kingdom.getCastle().getDescription()); | ||||||
|     LOGGER.info(kingdom.getKing().getDescription()); |     LOGGER.info(kingdom.getKing().getDescription()); | ||||||
|  |  | ||||||
|     LOGGER.info("Orc Kingdom"); |     LOGGER.info("orc kingdom"); | ||||||
|     createKingdom(Kingdom.FactoryMaker.KingdomType.ORC); |     createKingdom(Kingdom.FactoryMaker.KingdomType.ORC); | ||||||
|     LOGGER.info(kingdom.getArmy().getDescription()); |     LOGGER.info(kingdom.getArmy().getDescription()); | ||||||
|     LOGGER.info(kingdom.getCastle().getDescription()); |     LOGGER.info(kingdom.getCastle().getDescription()); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ 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() { | ||||||
|   | |||||||
| @@ -29,14 +29,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; | |||||||
| import static org.junit.jupiter.api.Assertions.assertTrue; | import static org.junit.jupiter.api.Assertions.assertTrue; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Test for abstract factory. |  * Tests for abstract factory. | ||||||
|  */ |  */ | ||||||
| class AbstractFactoryTest { | class AbstractFactoryTest { | ||||||
|  |  | ||||||
|   private final App app = new App(); |   private final App app = new App(); | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   void king() { |   void verifyKingCreation() { | ||||||
|     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); | ||||||
|     final var kingdom = app.getKingdom(); |     final var kingdom = app.getKingdom(); | ||||||
|  |  | ||||||
| @@ -51,7 +51,7 @@ class AbstractFactoryTest { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   void castle() { |   void verifyCastleCreation() { | ||||||
|     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); | ||||||
|     final var kingdom = app.getKingdom(); |     final var kingdom = app.getKingdom(); | ||||||
|  |  | ||||||
| @@ -66,7 +66,7 @@ class AbstractFactoryTest { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   void army() { |   void verifyArmyCreation() { | ||||||
|     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); | ||||||
|     final var kingdom = app.getKingdom(); |     final var kingdom = app.getKingdom(); | ||||||
|  |  | ||||||
| @@ -81,7 +81,7 @@ class AbstractFactoryTest { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   void createElfKingdom() { |   void verifyElfKingdomCreation() { | ||||||
|     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); | ||||||
|     final var kingdom = app.getKingdom(); |     final var kingdom = app.getKingdom(); | ||||||
|  |  | ||||||
| @@ -97,7 +97,7 @@ class AbstractFactoryTest { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   void createOrcKingdom() { |   void verifyOrcKingdomCreation() { | ||||||
|     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC); |     app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC); | ||||||
|     final var kingdom = app.getKingdom(); |     final var kingdom = app.getKingdom(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,10 +28,7 @@ import org.junit.jupiter.api.Test; | |||||||
| import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Issue: Add at least one assertion to this test case. |  * Check whether the execution of the main method in {@link App} throws an exception. | ||||||
|  * |  | ||||||
|  * Solution: Inserted assertion to check whether the execution of the main method in {@link App} |  | ||||||
|  * throws an exception. |  | ||||||
|  */ |  */ | ||||||
| class AppTest { | class AppTest { | ||||||
|      |      | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user