Skip to content

Commit 922c699

Browse files
authored
Merge pull request iluwatar#1516 from samilAyoub/add-simple-factory
Add Simple Factory Pattern implementation
2 parents 3df8472 + bf41b1d commit 922c699

File tree

13 files changed

+377
-0
lines changed

13 files changed

+377
-0
lines changed

factory/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
layout: pattern
3+
title: Factory
4+
folder: factory
5+
permalink: /patterns/factory/
6+
categories: Creational
7+
tags:
8+
- Gang of Four
9+
---
10+
11+
## Also known as
12+
13+
* Simple Factory
14+
* Static Factory Method
15+
16+
## Intent
17+
18+
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.
19+
20+
## Explanation
21+
22+
Real world example
23+
24+
> 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.
25+
26+
Wikipedia says
27+
28+
> 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.
29+
30+
**Programmatic Example**
31+
32+
We have an interface 'Car' and tow implementations 'Ford' and 'Ferrari'.
33+
34+
```java
35+
/**
36+
* Car interface.
37+
*/
38+
public interface Car {
39+
40+
public String getDescription();
41+
42+
}
43+
44+
/**
45+
* Ford implementation.
46+
*/
47+
public class Ford implements Car {
48+
49+
static final String DESCRIPTION = "This is Ford.";
50+
51+
@Override
52+
public String getDescription() {
53+
return DESCRIPTION;
54+
}
55+
}
56+
57+
/**
58+
* Ferrari implementation.
59+
*/
60+
public class Ferrari implements Car {
61+
62+
static final String DESCRIPTION = "This is Ferrari.";
63+
64+
@Override
65+
public String getDescription() {
66+
return DESCRIPTION;
67+
}
68+
}
69+
```
70+
71+
Enumeration above represents types of cars that we support (Ford and Ferrari).
72+
73+
```java
74+
public enum CarType {
75+
76+
/**
77+
* Enumeration for different types of cars.
78+
*/
79+
FORD(Ford::new),
80+
FERRARI(Ferrari::new);
81+
82+
private final Supplier<Car> constructor;
83+
84+
CarType(Supplier<Car> constructor) {
85+
this.constructor = constructor;
86+
}
87+
88+
public Supplier<Car> getConstructor() {
89+
return this.constructor;
90+
}
91+
}
92+
```
93+
Then we have the static method 'getCar' to create car objects encapsulated in the factory class 'CarSimpleFactory'.
94+
95+
```java
96+
/**
97+
* Factory of cars.
98+
*/
99+
public class CarsFactory {
100+
101+
/**
102+
* Factory method takes as parameter a car type and initiate the appropriate class.
103+
*/
104+
public static Car getCar(CarType type) {
105+
return type.getConstructor().get();
106+
}
107+
}
108+
```
109+
110+
Now on the client code we can create different types of cars using the factory class.
111+
112+
```java
113+
var car1 = CarsFactory.getCar(CarType.FORD);
114+
var car2 = CarsFactory.getCar(CarType.FERRARI);
115+
LOGGER.info(car1.getDescription());
116+
LOGGER.info(car2.getDescription());;
117+
```
118+
119+
Program output:
120+
121+
```java
122+
This is Ford.
123+
This Ferrari.
124+
```
125+
## Class Diagram
126+
![alt text](./etc/factory.urm.png "Factory pattern class diagram")
127+
128+
## Applicability
129+
Use the Simple Factory pattern when you only care about the creation of a object, not how to create and manage it.
130+
131+
## Pros
132+
* Allows keeping all objects creation in one place and avoid of spreading 'new' key value across codebase.
133+
* Allows to writs loosely coupled code. Some of its main advantages include better testability, easy-to-understand code, swappable components, scalability and isolated features.
134+
135+
## Cons
136+
* The code becomes more complicated than it should be.
137+
138+
## Related patterns
139+
140+
[Factory Method](https://java-design-patterns.com/patterns/factory-method/)
141+
[Factory Kit](https://java-design-patterns.com/patterns/factory-kit/)
142+
[Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/)
143+
144+

factory/etc/factory.urm.png

24.8 KB
Loading

factory/etc/factory.urm.puml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@startuml
2+
package com.iluwatar.factory {
3+
class App {
4+
- LOGGER : Logger {static}
5+
+ App()
6+
+ main(args : String[]) {static}
7+
}
8+
interface Car {
9+
+ getDescription() : String {abstract}
10+
}
11+
class CarsFactory {
12+
+ CarsFactory()
13+
+ getCar(type : CarType) : Car {static}
14+
}
15+
~enum CarType {
16+
+ FERRARI {static}
17+
+ FORD {static}
18+
+ valueOf(name : String) : CarType {static}
19+
+ values() : CarType[] {static}
20+
}
21+
class Ferrari {
22+
~ DESCRIPTION : String {static}
23+
+ Ferrari()
24+
+ getDescription() : String
25+
}
26+
class Ford {
27+
~ DESCRIPTION : String {static}
28+
+ Ford()
29+
+ getDescription() : String
30+
}
31+
}
32+
CarType ..+ CarsFactory
33+
Ferrari ..|> Car
34+
Ford ..|> Car
35+
@enduml

factory/pom.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.iluwatar</groupId>
7+
<artifactId>java-design-patterns</artifactId>
8+
<version>1.24.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>factory</artifactId>
11+
<dependencies>
12+
<dependency>
13+
<groupId>org.junit.jupiter</groupId>
14+
<artifactId>junit-jupiter-engine</artifactId>
15+
<scope>test</scope>
16+
</dependency>
17+
<dependency>
18+
<groupId>junit</groupId>
19+
<artifactId>junit</artifactId>
20+
</dependency>
21+
</dependencies>
22+
<build>
23+
<plugins>
24+
<!-- Maven assembly plugin is invoked with default setting which we have
25+
in parent pom and specifying the class having main method -->
26+
<plugin>
27+
<groupId>org.apache.maven.plugins</groupId>
28+
<artifactId>maven-assembly-plugin</artifactId>
29+
<executions>
30+
<execution>
31+
<configuration>
32+
<archive>
33+
<manifest>
34+
<mainClass>com.iluwatar.factory.App</mainClass>
35+
</manifest>
36+
</archive>
37+
</configuration>
38+
</execution>
39+
</executions>
40+
</plugin>
41+
</plugins>
42+
</build>
43+
</project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* The MIT License
3+
* Copyright © 2014-2019 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
package com.iluwatar.factory;
25+
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/**
30+
* Factory is an object for creating other objects, it providing Providing a static method to
31+
* create and return objects of varying classes, in order to hide the implementation logic
32+
* and makes client code focus on usage rather then objects initialization and management.
33+
*
34+
* <p>In this example the CarFactory is the factory class and it provides a static method to
35+
* create different cars.
36+
*/
37+
38+
public class App {
39+
40+
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
41+
42+
/**
43+
* Program main entry point.
44+
*/
45+
public static void main(String[] args) {
46+
var car1 = CarsFactory.getCar(CarType.FORD);
47+
var car2 = CarsFactory.getCar(CarType.FERRARI);
48+
LOGGER.info(car1.getDescription());
49+
LOGGER.info(car2.getDescription());
50+
}
51+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.iluwatar.factory;
2+
3+
/**
4+
* Car interface.
5+
*/
6+
public interface Car {
7+
8+
public String getDescription();
9+
10+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.iluwatar.factory;
2+
3+
import java.util.function.Supplier;
4+
5+
public enum CarType {
6+
7+
/**
8+
* Enumeration for different types of cars.
9+
*/
10+
FORD(Ford::new),
11+
FERRARI(Ferrari::new);
12+
13+
private final Supplier<Car> constructor;
14+
15+
CarType(Supplier<Car> constructor) {
16+
this.constructor = constructor;
17+
}
18+
19+
public Supplier<Car> getConstructor() {
20+
return this.constructor;
21+
}
22+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.iluwatar.factory;
2+
3+
/**
4+
* Factory of cars.
5+
*/
6+
public class CarsFactory {
7+
8+
/**
9+
* Factory method takes as parameter a car type and initiate the appropriate class.
10+
*/
11+
public static Car getCar(CarType type) {
12+
return type.getConstructor().get();
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.iluwatar.factory;
2+
3+
/**
4+
* Ferrari implementation.
5+
*/
6+
public class Ferrari implements Car {
7+
8+
static final String DESCRIPTION = "This is Ferrari.";
9+
10+
@Override
11+
public String getDescription() {
12+
return DESCRIPTION;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.iluwatar.factory;
2+
3+
/**
4+
* Ford implementation.
5+
*/
6+
public class Ford implements Car {
7+
8+
static final String DESCRIPTION = "This is Ford.";
9+
10+
@Override
11+
public String getDescription() {
12+
return DESCRIPTION;
13+
}
14+
}

0 commit comments

Comments
 (0)