Post

โ›“๏ธ Java Design-Pattern โ…ค - Factory Method

โ›“๏ธ Java Design-Pattern โ…ค - Factory Method

๐Ÿ“— ใ€ŽJAVA ์–ธ์–ด๋กœ ๋ฐฐ์šฐ๋Š” ๋””์ž์ธ ํŒจํ„ด : ์‰ฝ๊ฒŒ ๋ฐฐ์šฐ๋Š” GoF์˜ 23๊ฐ€์ง€ ๋””์ž์ธ ํŒจํ„ดใ€๋ฅผ ์ฝ๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

Factory Method ํŒจํ„ด์ด๋ž€?

  • ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐฉ๋ฒ•์„ ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ๊ฒฐ์ •ํ•˜๋˜, ์‹ค์ œ ์ธ์Šคํ„ด์Šค๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ƒ์„ฑํ•œ๋‹ค.
  • ์ฆ‰ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณต์žฅ์„ย Template Methodย ํŒจํ„ด์œผ๋กœ ๊ตฌ์„ฑํ•œ ๊ฒƒ์ด๋‹ค.

์˜ˆ์ œ ํ”„๋กœ๊ทธ๋žจ

  • frameworkย ํŒจํ‚ค์ง€์— ํฌํ•จ๋œย Product,ย Factoryย ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ผˆ๋Œ€ ์—ญํ• ์„ ํ•œ๋‹ค.
  • idcardย ํŒจํ‚ค์ง€์— ํฌํ•จ๋œย IDCard,ย IDCardFactoryย ํด๋ž˜์Šค๋Š” ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  • Mainย ํด๋ž˜์Šค๋Š” ๋™์ž‘ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค์ด๋‹ค.

Productย ํด๋ž˜์Šค

1
2
3
4
5
package framework;

public abstract class Product {
	public abstract void use();
}
  • ์ด ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ๋ฌด์—‡์ด๋“ ย useํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ œํ’ˆ์œผ๋กœ ๊ทœ์ •ํ•œ๋‹ค.

Factoryย ํด๋ž˜์Šค

1
2
3
4
5
6
7
8
9
10
11
12
package framework;

public abstract class Factory {
	public final Product create(String owner) {
    	Product p = createProduct(owner);
        registerProduct(p);
        return p;
    }
    
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(String product);
}
  • Template Methodย ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌย createย ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ดย Productย ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.ย 
  • createย ๋ฉ”์†Œ๋“œ ๋‚ดย createProduct,ย registerProductย ๋ฉ”์†Œ๋“œ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค.
  • ์ด์ฒ˜๋Ÿผย Factory Methodย ํŒจํ„ด์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œย Template Methodย ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค.

IDCardย ํด๋ž˜์Šค

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package idcard;

import framework.Product;

public class IDCard extends Product {
	private String owner;
    
    IDCard(String owner) {
    	System.out.println(owner + "์˜ ์นด๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.");
        this.owner = owner;
    }
    
    @Override
    public void use() {
    	System.out.println(this + "์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.");
    }
    
    @Override
    public String toString() {
    	return "[IDCard:" + owner + "]"
    }
    
    public String getOwner() {
    	return owner;
    }
}
  • Productย ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ์„œ ์ •์˜๋œ ํด๋ž˜์Šค์ด๋‹ค.

IDCardFactoryย ํด๋ž˜์Šค

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package idcard;

import framework.Factory;
import framework.Product;
import java.util.ArrayList;
import java.util.List;

public class IDCardFactory extends Factory {
    private List<String> owners = new ArrayList<>();
    
    @Override
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }
    
    @Override
    protected void registerProduct(Product product) {
        if (product instanceof IDCard) {
            IDCard card = (IDCard) product;
            owners.add(card.getOwner());
        }
    }
    
    public List<String> getOwners() {
        return owners;
    }
}

Mainย ํด๋ž˜์Šค

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import framework.Factory;
import framework.Product;
import idcard.IDCardFactory;

public class Main {
	public static void main(String args[]) {
    	Factory factory = new IDCardFactory();
        Product card1 = factory.create("๊น€์•„๋ฌด๊ฐœ");
        Product card2 = factory.create("๋ฐ•์•„๋ฌด๊ฐœ");
        Product card3 = factory.create("์ตœ์•„๋ฌด๊ฐœ");
        
        card1.use();
        card2.use();
        card3.use();
    }
}
  • ์‹ค์ œ๋กœย IDCardFactoryย ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๋™์ž‘ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค์ด๋‹ค.

Factory Methodย ํŒจํ„ด์˜ ๋“ฑ์žฅ์ธ๋ฌผ

Productย ํด๋ž˜์Šค

  • ํ”„๋ ˆ์ž„์›Œํฌ์— ํ•ด๋‹น๋˜๋ฉฐ, ์ œํ’ˆ์—ญํ• ๋กœ, ์ด ํŒจํ„ด์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ€์ ธ์•ผ ํ•  ์ธํ„ฐํŽ˜์ด์Šคย API๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์ด๋‹ค.

Factoryย ํด๋ž˜์Šค

  • ํ”„๋ ˆ์ž„์›Œํฌ์— ํ•ด๋‹น๋˜๋ฉฐ, ์ œํ’ˆ ์—ญํ• ์„ ์ƒ์„ฑํ•˜๋Š” ์ž‘์„ฑ์žย Creatorย ์—ญํ• ์„ ํ•œ๋‹ค.
  • ์‹ค์ œ๋กœ ์ƒ์„ฑํ• ย ConcreteProductย ์—ญํ• ์—๋Š” ์•„๋Š” ๋ฐ”๊ฐ€ ์—†๋‹ค.
  • ์˜ˆ์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š”ย newย ๋Œ€์‹ ย createProductย ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ์ด๋ฅผ ํ†ตํ•ด ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ๋ช…์— ์˜์กดํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
IDCardย ํด๋ž˜์Šค
  • ๊ตฌ์ฒด์ ์ธ ์ œํ’ˆย ConcreteProductย ์—ญํ• ์„ ๋งก์•„ ์ œํ’ˆ ์—ญํ• ์˜ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
IDCardFactoryย ํด๋ž˜์Šค
  • ๊ตฌ์ฒด์ ์ธ ์ž‘์„ฑ์žย ConcreteCreatorย ์—ญํ• ์„ ๋งก์•„ ์ž‘์„ฑ์ž ์—ญํ• ์˜ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์ฑ…์—์„œ ์ œ์‹œํ•˜๋Š” ํžŒํŠธ

ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ

  • ์—ฌ๊ธฐ์„œ ๊ฐ™์€ ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌย IDCard๊ฐ€ ์•„๋‹Œย TV๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.
  • ์ด ๊ฒฝ์šฐย frameworkย ํŒจํ‚ค์ง€๋ฅผย importํ•˜๋Š” ๋ณ„๊ฐœ์˜ย televisionย ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐ,ย frameworkย ํŒจํ‚ค์ง€ ๋‚ด ํด๋ž˜์Šค๋“ค์€ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ์™œ๋ƒํ•˜๋ฉดย frameworkย ํŒจํ‚ค์ง€ ๋‚ด์—์„œ๋Š”ย idcardย ํŒจํ‚ค์ง€๋ฅผย importย ํ•œ ์ ์ด ์—†๋‹ค.
  • ์ฆ‰ ํ•ด๋‹น ํŒจํ„ด์—์„œ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ธ์Šคํ„ด์Šค ์ƒ์„ฑ: ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

  • ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ธฐ์ˆ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 1. ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ๊ธฐ์ˆ  */
abstract class Factory {
	public abstract Product createProduct(String name);
	
    // ...
}

/* 2. ๋””ํดํŠธ ๊ตฌํ˜„์„ ์ค€๋น„ */
class Factory {
	public Product createProduct(String name) {
    	return new Product(name);
    }
}
  • ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ๊ธฐ์ˆ ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ˆ์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ, ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ๊ธฐ์ˆ ํ•  ๊ฒฝ์šฐ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š๋”๋ผ๋„ ์ปดํŒŒ์ผํ•  ๋•Œ ๊ฒ€์ถœ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.
  • ๋””ํดํŠธ ๊ตฌํ˜„์„ ์ค€๋น„ํ•˜๋Š” ๊ฒฝ์šฐ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋””ํดํŠธ ๊ตฌํ˜„์ด ์‚ฌ์šฉ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.
  • ๋‹ค๋งŒ,ย Productย ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ง์ ‘ย new๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœย Productย ํด๋ž˜์Šค๋ฅผ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋‘˜ ์ˆ˜ ์—†๋‹ค.

ํŒจํ„ด ์ด์šฉ๊ณผ ๊ฐœ๋ฐœ์ž ๊ฐ„์˜ ์˜์‚ฌ์†Œํ†ต

  • ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋งŒ ์ฝ์–ด์„œ๋Š” ๋™์ž‘์„ ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ๋™์ž‘์˜ ๋ผˆ๋Œ€๋ฅผ ์ดํ•ดํ•œ ํ›„ ๊ฑฐ๊ธฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•˜๊ณ , ๋‹ค์‹œ ๊ทธ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์•„์•ผ ํ•œ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋””์ž์ธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด ์–ด๋–ค ํด๋ž˜์Šค ๊ตฐ์„ ์„ค๊ณ„ํ•  ๊ฒฝ์šฐ, ์„ค๊ณ„์ž๊ฐ€ ๋ณด์ˆ˜์ž์—๊ฒŒ ์˜๋„ํ•œ ๋””์ž์ธ ํŒจํ„ด์ด ๋ฌด์—‡์ธ์ง€ ์ž˜ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
  • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„ค๊ณ„์ž์˜ ์˜๋„์—์„œ ๋ฒ—์–ด๋‚œ ์ˆ˜์ •์ด ๊ฐ€ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ฃผ์„์ด๋‚˜ ๊ฐœ๋ฐœ ๋ฌธ์„œ์— ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด์˜ ๋ช…์นญ๊ณผ ์˜๋„๋ฅผ ๊ธฐ์ˆ ํ•˜์—ฌ ๋‘๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.

static Factory Method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 1. java.security.SecureRandom */
SecureRandom random = SecureRandom.getInstance("NativePRNG");

/* 2. java.util.List */
List<String> list = List.of("Alice", "Bob");

/* 3. java.util.Arrays */
String[] arr = {"Alice", "Bob"};
List<String> list = Arrays.asList(arr);

/* 4. java.lang.String */
String string = String.valueOf('A');

/* 5. java.time.Instant */
Instant instant = Instant.now();
  • ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ์œ„ํ•œย staticย ๋ฉ”์†Œ๋“œ ์ „๋ฐ˜์„ย Factory Method๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
  • ์ด๊ฒƒ์€ย GoF์˜ย Factory Methodย ํŒจํ„ด๊ณผ๋Š” ๋‹ค๋ฅด์ง€๋งŒย Java์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.
  • Java APIย ๋ž˜ํผ๋Ÿฐ์Šค์—์„œ๋„ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ์œ„ํ•œ ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋ฅผย static Factory Method๋กœ ํ‘œํ˜„ํ•˜๊ธฐ๋„ ํ•˜๋ฏ€๋กœย Java APIย ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฝ์„ ๋•Œ๋Š” ์ฐธ์กฐํ•˜๋Š” ํด๋ž˜์Šค์—ย static Factory Method๊ฐ€ ์ œ๊ณต๋˜๋Š”์ง€ ์ฃผ๋ชฉํ•ด์•ผ ํ•œ๋‹ค.
  • create,ย newInstance,ย getInstanceย ๋“ฑ์˜ ์ด๋ฆ„์ด ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ๊ทธ ๋ฐ–์˜ ์ด๋ฆ„์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
This post is licensed under CC BY 4.0 by the author.