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) {
}
This post is licensed under CC BY 4.0 by the author.
