Creational_Factory
- Loose coupling
- OC principle
defaultin interface
π οΈ When to use factory
- When you want to create several types of smth with different values
- give the creation role to a factory
- π You have class
CircleandSquareextendingInterface Shape - you want to create
CircleorSquareusing one constructor - π You have class
WhiteShipandBlackShipextendingShip - you want to create
WhiteShipandBlackShipjust with one method, without usingelse-iffor checking the names and settings colorsβ¦
β Factory Pattern
- factoryμμμ ꡬ체μ μΈ ν΄λμ€λ₯Ό λ§λ€μ΄λΈλ€
- βοΈ Loosely coupled: make coupling between class and constructor loose
<<Interface>>will be responsible for constructing a class- delegate object creation to a factory
- βοΈ Open/Closed principle: open to extension, closed to modification
ππ» If there was no factory pattern
- βοΈ Class
Ship
1
2
3
4
5
6
7
8
public class Ship {
private String name;
private String color;
private String logo;
//getters
//setters
}
- βοΈ Class
ShipFactory - ππ» need to check name and set logo and color accordingly
1
2
3
4
5
6
7
8
9
10
11
12
13
// Customizing for specific name
if (name.equalsIgnoreCase("whiteship")) {
ship.setLogo("\uD83D\uDEE5οΈ");
} else if (name.equalsIgnoreCase("blackship")) {
ship.setLogo("β");
}
// coloring
if (name.equalsIgnoreCase("whiteship")) {
ship.setColor("whiteship");
} else if (name.equalsIgnoreCase("blackship")) {
ship.setColor("black");
}
β After factory pattern
- βοΈ Class
Ship
1
2
3
4
5
6
7
8
public class Ship {
private String name;
private String color;
private String logo;
//getters
//setters
}
- βοΈ Class
WhiteShipandBlackShip - βοΈ How to set attributes of parent without using constructor
1
2
3
4
5
6
7
public class WhiteShip extends Ship {
public WhiteShip() {
setName("White Ship");
setLogo("aaa");
setColor("white");
}
}
1
2
3
4
5
6
7
public class BlackShip extends Ship{
public BlackShip() {
setName("BlackShip");
setLogo("bbbb");
setColor("black");
}
}
- βοΈ Interface ShipFactory
1
2
3
4
5
6
7
8
9
10
11
12
public interface ShipFactory {
//default, could/could not be overrided
default Ship orderShip(String name, String email){
validate(name, email);
Ship ship = createShip(); //use createShip();
sendEmailTo(email, ship);
return ship;
}
Ship createShip(); //not defined, must be overrided
}
validate(),sendEmailTo()are methods I want to run as soon as I create ShipβοΈ Class WhiteShipFactory and BlackShipFactory
1
2
3
4
5
6
public class WhiteShipFactory implements ShipFactory{
@Override
public Ship createShip() {
return new WhiteShip();
}
}
1
2
3
4
5
6
public class BlackShipFactory implements ShipFactory{
@Override
public Ship createShip() {
return new BlackShip();
}
}
- βοΈ CLient code
1
2
3
4
5
6
public class Client {
public static void main(String[] args) {
Ship whiteShip = new WhiteShipFactory().orderShip("WhiteShip", "aaa@gmail.com");
Ship blackShip = new BlackShipFactory().orderShip("BlackShip", "bbb@gmail.com");
}
}
ππ» Advantages ππ» Disadvantages
- ππ» do not need to use else-if
- ππ» open/closed principle: open for extension, closed for modification
- can create another function/interface without modifying the old code
- this is bc of coupling between class and constructor is loose
ππ» can use
defaultto write a default method ininterface- ππ» need to create more classes
default and private in interface
- can use
defaultto define a method ininterface - and the helper methods for the
default methodshould beprivate - as it would be used only inside the interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface ShipFactory {
default Ship orderShip(String name, String email){
validate(name, email);
prepareFor(name);
Ship ship = createShip();
sendEmailTo(email, ship);
return ship;
}
//helper methods inside default method
//access modifier: private
private void validate(String name, String email){
}
private void prepareFor(String name) {
}
π
βοΈ Product interface
1
2
3
4
public interface Car {
//method that car can perform
drive();
}
βοΈ Abstract product
1
2
3
4
5
6
7
8
9
10
public abstract class AbstractCar implements Car {
protected String color;
protected double price;
//constructor to use in concrete products
public AbstractCar(String color, double price) {
this.color = color;
this.price = price;
}
}
βοΈ Concete products
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Mercedes extends AbstractCar {
public Mercedes(String color) {
super(color, 55000);
}
@Override
public void drive() {
}
}
public class Kia extends AbstractCar {
public Kia(String color) {
super(color, 30000);
}
@Override
public void drive() {
}
}
βοΈ Factory Interface
1
2
3
4
5
public interface CarFactory {
Car createCar(String color);
}
βοΈ Conrete Factory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MercedesFactory implements CarFactory {
@Override
public Car createCar(String color) {
return new Mercedes(color);
}
}
public class KiaFactory implements CarFactory {
@Override
public Car createCar(String color) {
return new Kia(color);
}
}
βοΈ Client
1
2
3
Car blackMercedes = new MercedesFactory.createCar("black");
Car whiteKia = new KiaFactory.createCar("white");
This post is licensed under CC BY 4.0 by the author.

