Skip to content

Commit badf0c6

Browse files
committed
- README.md is added
- Change the name to factory is done - Local variable type inference is used
1 parent 8afe4c3 commit badf0c6

File tree

10 files changed

+347
-0
lines changed

10 files changed

+347
-0
lines changed

factory/README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
Then we have the static method "getCar" to create car objects encapsulated in the factory class "CarSimpleFactory".
72+
73+
```java
74+
/**
75+
* Factory of cars.
76+
*/
77+
public class CarSimpleFactory {
78+
79+
/**
80+
* Enumeration for different types of cars.
81+
*/
82+
static enum CarType {
83+
FORD, FERRARI
84+
}
85+
86+
/**
87+
* Factory method takes as parameter a car type and initiate the appropriate class.
88+
*/
89+
public static Car getCar(CarType type) {
90+
switch (type) {
91+
case FORD: return new Ford();
92+
case FERRARI: return new Ferrari();
93+
default: throw new IllegalArgumentException("Model not supported.");
94+
}
95+
}
96+
}
97+
```
98+
99+
Now on the client code we can create differentes types of cars(Ford or Ferrari) using the factory class.
100+
101+
```java
102+
Car car1 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FORD);
103+
Car car2 = CarSimpleFactory.getCar(CarSimpleFactory.CarType.FERRARI);
104+
LOGGER.info(car1.getDescription());
105+
LOGGER.info(car2.getDescription());
106+
```
107+
108+
Program output:
109+
110+
```java
111+
This is Ford.
112+
This Ferrari.
113+
```
114+
## Applicability
115+
116+
Use the Simple Factory pattern when you only care about the creation of a object, not how to create and manage it.
117+
118+
## Disadvantages:
119+
120+
The code becomes more complicated than it should be.
121+
122+
## Related patterns
123+
124+
[Factory Method](https://java-design-patterns.com/patterns/factory-method/)
125+
[Factory Kit](https://java-design-patterns.com/patterns/factory-kit/)
126+
[Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/)
127+
128+

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: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<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">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>com.iluwatar</groupId>
5+
<artifactId>java-design-patterns</artifactId>
6+
<version>1.24.0-SNAPSHOT</version>
7+
</parent>
8+
<artifactId>factory</artifactId>
9+
<dependencies>
10+
<dependency>
11+
<groupId>org.junit.jupiter</groupId>
12+
<artifactId>junit-jupiter-engine</artifactId>
13+
<scope>test</scope>
14+
</dependency>
15+
<dependency>
16+
<groupId>junit</groupId>
17+
<artifactId>junit</artifactId>
18+
</dependency>
19+
</dependencies>
20+
<build>
21+
<plugins>
22+
<!-- Maven assembly plugin is invoked with default setting which we have
23+
in parent pom and specifying the class having main method -->
24+
<plugin>
25+
<groupId>org.apache.maven.plugins</groupId>
26+
<artifactId>maven-assembly-plugin</artifactId>
27+
<executions>
28+
<execution>
29+
<configuration>
30+
<archive>
31+
<manifest>
32+
<mainClass>com.iluwatar.factory.App</mainClass>
33+
</manifest>
34+
</archive>
35+
</configuration>
36+
</execution>
37+
</executions>
38+
</plugin>
39+
</plugins>
40+
</build>
41+
</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(CarsFactory.CarType.FORD);
47+
var car2 = CarsFactory.getCar(CarsFactory.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: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.iluwatar.factory;
2+
3+
/**
4+
* Factory of cars.
5+
*/
6+
public class CarsFactory {
7+
8+
/**
9+
* Enumeration for different types of cars.
10+
*/
11+
static enum CarType {
12+
FORD, FERRARI
13+
}
14+
15+
/**
16+
* Factory method takes as parameter a car type and initiate the appropriate class.
17+
*/
18+
public static Car getCar(CarType type) {
19+
switch (type) {
20+
case FORD: return new Ford();
21+
case FERRARI: return new Ferrari();
22+
default: throw new IllegalArgumentException("Model not supported.");
23+
}
24+
}
25+
}
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+
}
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+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
class AppTest {
8+
9+
@Test
10+
void shouldExecuteWithoutExceptions() {
11+
assertDoesNotThrow(() -> App.main(new String[]{}));
12+
}
13+
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.iluwatar.factory;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
class CarsFactoryTest {
8+
9+
@Test
10+
void shouldReturnFerrariInstance() {
11+
final var ferrari = CarsFactory.getCar(CarsFactory.CarType.FERRARI);
12+
assertTrue(ferrari instanceof Ferrari);
13+
}
14+
15+
}

0 commit comments

Comments
 (0)