Post

Creational_Factory

  • Loose coupling
  • OC principle
  • default in 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 Circle and Square extending Interface Shape
  • you want to create Circle or Square using one constructor
  • πŸ‘€ You have class WhiteShip and BlackShip extending Ship
  • you want to create WhiteShip and BlackShip just with one method, without using else-if for 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

Screenshot-2026-02-19-at-15-45-43.png

  • βœ”οΈ 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 WhiteShip and BlackShip
  • ⭐️ 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 default to write a default method in interface

  • πŸ‘ŽπŸ» need to create more classes

default and private in interface

  • can use default to define a method in interface
  • and the helper methods for the default method should be private
  • 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) {

    }


πŸ‘€

Screenshot-2026-03-08-at-10-04-25.png

βœ”οΈ 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.