- README.md is added
- Change the name to factory is done - Local variable type inference is used
This commit is contained in:
		
							
								
								
									
										128
									
								
								factory/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								factory/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| --- | ||||
| layout: pattern | ||||
| title: Factory | ||||
| folder: factory | ||||
| permalink: /patterns/factory/ | ||||
| categories: Creational | ||||
| tags: | ||||
|  - Gang of Four | ||||
| --- | ||||
|  | ||||
| ## Also known as | ||||
|  | ||||
| * Simple Factory | ||||
| * Static Factory Method | ||||
|  | ||||
| ## Intent | ||||
|  | ||||
| Providing a static method encapsulated in a class called factory, in order to hide the implementation logic and makes client code focus on usage rather then initialization new objects. | ||||
|  | ||||
| ## Explanation | ||||
|  | ||||
| Real world example | ||||
|  | ||||
| > Lets say we have a web application connected to SQLServer, but now we want to switch to Oracle. To do so without modifying existing source code, we need to implements Simple Factory pattern, in which a static method can be invoked to create connection to a given database. | ||||
|  | ||||
| Wikipedia says | ||||
|  | ||||
| > Factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class. | ||||
|  | ||||
| **Programmatic Example** | ||||
|  | ||||
| We have an interface "Car" and tow implementations "Ford" and "Ferrari". | ||||
|  | ||||
| ```java | ||||
| /** | ||||
|  * Car interface. | ||||
|  */ | ||||
| public interface Car { | ||||
|    | ||||
|   public String getDescription(); | ||||
|    | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Ford implementation. | ||||
|  */ | ||||
| public class Ford implements Car { | ||||
|  | ||||
|   static final String DESCRIPTION = "This is Ford."; | ||||
|  | ||||
|   @Override | ||||
|   public String getDescription() { | ||||
|     return DESCRIPTION; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Ferrari implementation. | ||||
|  */ | ||||
| public class Ferrari implements Car { | ||||
|     | ||||
|   static final String DESCRIPTION = "This is Ferrari."; | ||||
|  | ||||
|   @Override | ||||
|   public String getDescription() { | ||||
|     return DESCRIPTION; | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Then we have the static method "getCar" to create car objects encapsulated in the factory class "CarSimpleFactory". | ||||
|  | ||||
| ```java | ||||
| /** | ||||
|  * Factory of cars. | ||||
|  */ | ||||
| public class CarSimpleFactory { | ||||
|    | ||||
|   /** | ||||
|    * Enumeration for different types of cars. | ||||
|    */ | ||||
|   static enum CarType { | ||||
|     FORD, FERRARI | ||||
|   } | ||||
|    | ||||
|   /** | ||||
|    * Factory method takes as parameter a car type and initiate the appropriate class. | ||||
|    */ | ||||
|   public static Car getCar(CarType type) { | ||||
|     switch (type) { | ||||
|       case FORD: return new Ford(); | ||||
|       case FERRARI: return new Ferrari(); | ||||
|       default: throw new IllegalArgumentException("Model not supported."); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Now on the client code we can create differentes types of cars(Ford or Ferrari) using the factory class. | ||||
|  | ||||
| ```java | ||||
| Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FORD); | ||||
| Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI); | ||||
| LOGGER.info(car1.getDescription()); | ||||
| LOGGER.info(car2.getDescription()); | ||||
| ``` | ||||
|  | ||||
| Program output: | ||||
|  | ||||
| ```java | ||||
| This is Ford. | ||||
| This Ferrari. | ||||
| ``` | ||||
| ## Applicability | ||||
|  | ||||
| Use the Simple Factory pattern when you only care about the creation of a object, not how to create and manage it. | ||||
|  | ||||
| ## Disadvantages: | ||||
|  | ||||
| The code becomes more complicated than it should be.  | ||||
|  | ||||
| ## Related patterns | ||||
|  | ||||
| [Factory Method](https://java-design-patterns.com/patterns/factory-method/) | ||||
| [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/) | ||||
| [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/) | ||||
|  | ||||
|  | ||||
							
								
								
									
										35
									
								
								factory/etc/factory.urm.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								factory/etc/factory.urm.puml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| @startuml | ||||
| package com.iluwatar.factory { | ||||
|   class App { | ||||
|     - LOGGER : Logger {static} | ||||
|     + App() | ||||
|     + main(args : String[]) {static} | ||||
|   } | ||||
|   interface Car { | ||||
|     + getDescription() : String {abstract} | ||||
|   } | ||||
|   class CarsFactory { | ||||
|     + CarsFactory() | ||||
|     + getCar(type : CarType) : Car {static} | ||||
|   } | ||||
|   ~enum CarType { | ||||
|     + FERRARI {static} | ||||
|     + FORD {static} | ||||
|     + valueOf(name : String) : CarType {static} | ||||
|     + values() : CarType[] {static} | ||||
|   } | ||||
|   class Ferrari { | ||||
|     ~ DESCRIPTION : String {static} | ||||
|     + Ferrari() | ||||
|     + getDescription() : String | ||||
|   } | ||||
|   class Ford { | ||||
|     ~ DESCRIPTION : String {static} | ||||
|     + Ford() | ||||
|     + getDescription() : String | ||||
|   } | ||||
| } | ||||
| CarType ..+ CarsFactory | ||||
| Ferrari ..|> Car  | ||||
| Ford ..|> Car  | ||||
| @enduml | ||||
							
								
								
									
										41
									
								
								factory/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								factory/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
|   <parent> | ||||
|     <groupId>com.iluwatar</groupId> | ||||
|     <artifactId>java-design-patterns</artifactId> | ||||
|     <version>1.24.0-SNAPSHOT</version> | ||||
|   </parent> | ||||
|   <artifactId>factory</artifactId> | ||||
|   <dependencies> | ||||
|     <dependency> | ||||
|       <groupId>org.junit.jupiter</groupId> | ||||
|       <artifactId>junit-jupiter-engine</artifactId> | ||||
|       <scope>test</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>junit</groupId> | ||||
|       <artifactId>junit</artifactId> | ||||
|     </dependency> | ||||
|   </dependencies> | ||||
|   <build> | ||||
| 		<plugins> | ||||
| 			<!-- Maven assembly plugin is invoked with default setting which we have  | ||||
| 				in parent pom and specifying the class having main method --> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-assembly-plugin</artifactId> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<configuration> | ||||
| 							<archive> | ||||
| 								<manifest> | ||||
| 									<mainClass>com.iluwatar.factory.App</mainClass> | ||||
| 								</manifest> | ||||
| 							</archive> | ||||
| 						</configuration> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
							
								
								
									
										51
									
								
								factory/src/main/java/com/iluwatar/factory/App.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								factory/src/main/java/com/iluwatar/factory/App.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  * Factory is an object for creating other objects, it providing Providing a static method to  | ||||
|  * create and return objects of varying classes, in order to hide the implementation logic  | ||||
|  * and makes client code focus on usage rather then objects initialization and management. | ||||
|  *  | ||||
|  * <p>In this example the CarFactory is the factory class and it provides a static method to  | ||||
|  * create different cars. | ||||
|  */ | ||||
|  | ||||
| public class App { | ||||
|    | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||
|    | ||||
|   /** | ||||
|    * Program main entry point. | ||||
|    */ | ||||
|   public static void main(String[] args) { | ||||
|     var car1 = CarsFactory.getCar(CarsFactory.CarType.FORD); | ||||
|     var car2 = CarsFactory.getCar(CarsFactory.CarType.FERRARI); | ||||
|     LOGGER.info(car1.getDescription()); | ||||
|     LOGGER.info(car2.getDescription()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								factory/src/main/java/com/iluwatar/factory/Car.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								factory/src/main/java/com/iluwatar/factory/Car.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| /** | ||||
|  * Car interface. | ||||
|  */ | ||||
| public interface Car { | ||||
|    | ||||
|   public String getDescription(); | ||||
|    | ||||
| } | ||||
							
								
								
									
										25
									
								
								factory/src/main/java/com/iluwatar/factory/CarsFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								factory/src/main/java/com/iluwatar/factory/CarsFactory.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| /** | ||||
|  * Factory of cars. | ||||
|  */ | ||||
| public class CarsFactory { | ||||
|    | ||||
|   /** | ||||
|    * Enumeration for different types of cars. | ||||
|    */ | ||||
|   static enum CarType { | ||||
|     FORD, FERRARI | ||||
|   } | ||||
|    | ||||
|   /** | ||||
|    * Factory method takes as parameter a car type and initiate the appropriate class. | ||||
|    */ | ||||
|   public static Car getCar(CarType type) { | ||||
|     switch (type) { | ||||
|       case FORD: return new Ford(); | ||||
|       case FERRARI: return new Ferrari(); | ||||
|       default: throw new IllegalArgumentException("Model not supported."); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										14
									
								
								factory/src/main/java/com/iluwatar/factory/Ferrari.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								factory/src/main/java/com/iluwatar/factory/Ferrari.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| /** | ||||
|  * Ferrari implementation. | ||||
|  */ | ||||
| public class Ferrari implements Car { | ||||
|     | ||||
|   static final String DESCRIPTION = "This is Ferrari."; | ||||
|  | ||||
|   @Override | ||||
|   public String getDescription() { | ||||
|     return DESCRIPTION; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										14
									
								
								factory/src/main/java/com/iluwatar/factory/Ford.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								factory/src/main/java/com/iluwatar/factory/Ford.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| /** | ||||
|  * Ford implementation. | ||||
|  */ | ||||
| public class Ford implements Car { | ||||
|  | ||||
|   static final String DESCRIPTION = "This is Ford."; | ||||
|  | ||||
|   @Override | ||||
|   public String getDescription() { | ||||
|     return DESCRIPTION; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										14
									
								
								factory/src/test/java/com/iluwatar/factory/AppTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								factory/src/test/java/com/iluwatar/factory/AppTest.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
|  | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| class AppTest { | ||||
|  | ||||
| 	@Test | ||||
| 	void shouldExecuteWithoutExceptions() { | ||||
| 		assertDoesNotThrow(() -> App.main(new String[]{})); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,15 @@ | ||||
| package com.iluwatar.factory; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
|  | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| class CarsFactoryTest { | ||||
|  | ||||
| 	@Test | ||||
| 	void shouldReturnFerrariInstance() { | ||||
| 		final var ferrari = CarsFactory.getCar(CarsFactory.CarType.FERRARI); | ||||
| 		assertTrue(ferrari instanceof Ferrari); | ||||
| 	} | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user