1. ๊ฐ๋จํ ํฉํ ๋ฆฌ ํจํด
๋จผ์ ๊ฐ๋จํ ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ค์ด๋ณด๊ณ ์ด๋ฅผ ์ ์ง์ ์ผ๋ก ํจํด์ ์ ์ฉํ์ฌ ์ ๊ทธ๋ ์ด๋ ํ๋ ์์ผ๋ก ์งํํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ์๋์ ๋ ธํธ๋ถ์ ์์ฑํ๋ ํจ์๊ฐ ์์ต๋๋ค. ๋งค๊ฐ๋ณ์ type์ ๋ฐ๋ผ์ ๋ ธํธ๋ถ์ ์์ฑํ๊ณ ์ค๋น, ์ค์ , ํฌ์ฅํด์ ์ต์ข ์ ์ผ๋ก ๋ ธํธ๋ถ์ ๋ฐํํ๊ฒ ๋ฉ๋๋ค.
public NoteBook creatNoteBook(String type) {
NoteBook noteBook;
if(type.equals("Macbook")) {
noteBook = new MackBook();
} else if (type.equals("LG Gram")) {
noteBook = new LGGram();
} else if (type.equals("GalaxyBook")) {
noteBook = new GalaxyBook();
} else if (... ...) {
...
}
noteBook.prepare();
noteBook.make();
noteBook.boxing();
return noteBook;
}
1.1 ๋ณํ๋ ๊ฒ๊ณผ ๋ณํ์ง ์๋ ๊ฒ
๋จผ์ ๋ณํ๋ ๊ฒ๊ณผ ๋ณํ์ง ์๋ ๊ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค.
1.1.1 ๋ณํ๋ ๊ฒ
๋ ธํธ๋ถ์ ์์ฑํ๋ ์ฝ๋๋ Type์ด ๋ง์์ง๋ฉด ๊ทธ๋งํผ if-else๋ฌธ๋ ๊ธธ์ด์ง ๊ฒ์ ๋๋ค.
if(type.equals("Macbook")) {
noteBook = new MackBook();
} else if (type.equals("LG Gram")) {
noteBook = new LGGram();
} else if (type.equals("GalaxyBook")) {
noteBook = new GalaxyBook();
} else if (... ...) {
...
}
1.1.2 ๋ณํ์ง ์๋ ๊ฒ
๋ ธํธ๋ถ ์ข ๋ฅ์ ์๊ด์์ด ์ค๋นํ๊ณ , ์ค์ ํ๊ณ , ํฌ์ฅํ๋ ๊ฒ์ ๋ณํ์ง ์์ต๋๋ค.
noteBook.prepare();
noteBook.make();
noteBook.boxing();
1.2 ๋์ ๋ถ๋ฆฌํด๋ณด์
1.2.1 NoteBook์ ์์ฐํ๋ ๊ฐ๋จํ ํฉํ ๋ฆฌ
๋ ธํธ๋ถ์ ์์ฑํ๋ ์ฝ๋๋ฅผ ์ด์ Factory๋ผ๋ ๊ฐ์ฒด๊ฐ ๋งก๊ธฐ๋ก ํ์ต๋๋ค.
public class SimpleNoteBookFactory {
public NoteBook createNoteBook(String type) {
NoteBook noteBook;
if(type.equals("Macbook")) {
noteBook = new MackBook();
} else if (type.equals("LG Gram")) {
noteBook = new LGGram();
} else if (type.equals("GalaxyBook")) {
noteBook = new GalaxyBook();
} else if (... ...) {
...
}
return noteBook;
}
}
1.2.2 ๋ ธํธ๋ถ์ ํ๋งคํ๋ ์คํ ์ด
Store์์๋ Factory์์ ์์ฑ๋ ๋ ธํธ๋ถ์ ๋ฐ์์ ์ค๋นํ๊ณ , ์ค์ ํ๊ณ , ํฌ์ฅํ๋ ์ผ์ ๋ด๋นํฉ๋๋ค.
public class NoteBookStore {
SimpleNoteBookFactory noteBookFactory;
public NoteBookStore(SimpleNoteBookFactory noteBookFactory) {
this.noteBookFactory = noteBookFactory;
}
public NoteBook orderNoteBook(String type) {
NoteBook noteBook = noteBookFactory.createNoteBook(type);
noteBook.prepare();
noteBook.make();
noteBook.boxing();
return noteBook;
}
}
์ ๋ฆฌ
๊ฐ๋จํ ํฉํ ๋ฆฌ(๋จ์ ํฉํ ๋ฆฌ)๋ ๋์์ธ ํจํด์ด ์๋๋๋ค. ํฉํ ๋ฆฌ ๋ฉ์๋ ๋๋ ์ถ์ ํฉํ ๋ฆฌ ํจํด์ ๋์ ํ๋ ์ค๊ฐ ๋จ๊ณ๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
๐ก ์ฅ์
- ๋ณํ๋ ๋ถ๋ถ๊ณผ ๋ณํ์ง ์๋ ๋ถ๋ถ์ ๋ถ๋ฆฌ
- ๋จ์ผ ์ฑ ์ ์์น
๐ก ๋จ์
- ํ๋์ ํฉํ ๋ฆฌ์์ ์ฌ๋ฌ ๊ฐ์ ํด๋์ค๋ฅผ ์์ฑ
- ํด๋์ค๊ฐ ๋์ด๋๋ค๋ฉด if-else๋ฌธ ๊ธธ์ด๋ ํจ๊ป ๋์ด๋จ
2. ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด(Factory Method Pattern)
2.1 ์ ์กฐ์ฌ ๋ง๋ค ์คํ ์ด ์์ฑ
๊ฐ ๋ ธํธ๋ถ ์ ์กฐ์ฌ๋ง๋ค ์คํ ์ด๋ฅผ ๋ง๋ค๊ธฐ ์ํด ํ๋์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด์ผ ํฉ๋๋ค. ๊ทธ๋์ผ ์๋ก์ด ์ ์กฐ์ฌ๊ฐ ๋ฑ์ฅํด๋ ์ ์ฐํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
public abstract class NoteBookStore {
public NoteBook class orderNoteBook(String type) {
NoteBook noteBook = createNoteBook(type);
noteBook.prepare();
noteBook.make();
noteBook.boxing();
return noteBook;
}
public abstract NoteBook createNoteBook();
}
์ด๋ ๊ฒ ํ๊ฒ ๋๋ฉด, ๊ฐ ์ ์กฐ์ฌ์์๋ noteBook์ ๋ง๋๋ ์ฝ๋๋ฅผ ๊ตฌํํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด ๊ฐ ์ ์กฐ์ฌ์ ๋ ธํธ๋ถ ์์ฑ ์ฝ๋๋ ๊ฐ ์ ์กฐ์ฌ์คํ ์ด์ ์บก์ํ๊ฐ ๋๊ฒ ๋ฉ๋๋ค.
๐ก ํฉํ ๋ฆฌ ๋ฉ์๋ ๋ฑ์ฅ public abstract NoteBook createNoteBook(String type);
ํฉํ ๋ฆฌ ๋ฉ์๋๋ ๊ฐ์ฒด ์์ฑ์ ์ฒ๋ฆฌํ๋ฉฐ, ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์์ ์ ์๋ธ ํด๋์ค์ ์บก์ํ์ํฌ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ํผํด๋์ค์ ์๋ ํด๋ผ์ด์ธํธ ์ฝ๋์ ์๋ธํด๋์ค์ ์๋ ๊ฐ์ฒด ์์ฑ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํ ์ ์์ต๋๋ค.
2.1.1 AppleStore ์์ฑ
public class MacBookStore extends NoteBookStore {
public NoteBook createNoteBook(String type) {
return new MackBook(...); // ๋งค๊ฐ๋ณ์ ์๋ต
}
}
2.2 NoteBook ํด๋์ค ์์ฑ
public abstract class NoteBook {
String name;
String cpu;
String ram;
String storage;
String display;
String os;
public void prepare() {
System.out.println("Preparing.. " + "name=" + name + ", cpu=" + cpu + ", ram=" + ram + ", storage=" + storage + ", display=" + display + ", os=" + os);
}
public void make() {
System.out.println("Make NoteBook...");
}
public void boxing() {
System.out.println("Boxing NoteBook...");
}
}
2.2.1 NoteBook ์๋ธ ํด๋์ค ์์
MacBook์ด๋ผ๋ฉด ์๋ ์ฒ๋ผ ๋ง๋ค ์ ์์ต๋๋ค.
public class MacBook extends NoteBook {
public MacBook() {
this.name = "MacBook";
this.cpu = "M2";
this.ram = "16GB";
this.storage = "SSD 500GB";
this.display = "Letina Display";
this.os = "macOS";
}
}
2.3 ์ค์ ๋ ธํธ๋ถ์ ์ฃผ๋ฌธํด๋ณด์
public class Main {
public static void main(String[] agrs) {
NoteBookStore store = new MacBookStore();
NoteBook noteBook = store.orderNoteBook();
System.out.println("My Order NoteBook is " + noteBook.getName());
}
}
์ ๋ฆฌ
ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ๊ฐ์ฒด ์์ฑ์ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ณ , ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ์ผ์ ์๋ธํด๋์ค์๊ฒ ์์ํฉ๋๋ค.
๐ก ์ฅ์
- ๊ฐ์ฒด ์์ฑ์ ์ํ ์ธํฐํ์ด์ค ์ ๊ณต (๊ฐ๋ฐฉ/ํ์ ์์น)
- ์๋ธ ํด๋์ค์๊ฒ ๊ฐ์ฒด ์์ฑ์ ์์ (๋จ์ผ ์ฑ ์ ์์น)
- ์์ฑํ๋ ๋ถ๋ถ๊ณผ ์ฌ์ฉํ๋ ๋ถ๋ถ์ ๋ถ๋ฆฌํ์ฌ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถค
๐ก ๋จ์
- ํจํด์ ๊ตฌํํ๊ธฐ ์ํด ์๋ธ ํด๋์ค๋ค์ด ๋ง์์ ธ ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์
3. ์ถ์ ํฉํ ๋ฆฌ ํจํด(Abstract Fatory Pattern)
3.1 AbstractFactory
๊ฐ ์ ์กฐ์ฌ์ ๋ถํ๋ค์ ์์ฑํ๋ ๊ณต์ฅ์ ๋ง๋ค๊ธฐ ์ ์, ์ถ์ ํฉํ ๋ฆฌ๋ฅผ ํ๋ ์์ฑํฉ๋๋ค. ๊ฐ ๊ณต์ฅ์์ ์ด๋ป๊ฒ ๋ถํ์ ์์ฐํ๋์ง์ ๋ํ ํ๋๋ค์ด ์ ํด์ ธ์์ต๋๋ค. ์ด์ ๊ฐ ์ ์กฐ์ฌ ๊ณต์ฅ๋ค์ AbstractFactory๋ฅผ ๊ตฌํํด์ ๊ฐ ์ ํ์ ๋ง๋ ๋ถํ๋ค์ ์์ฐํด๋ด๋ฉด ๋ฉ๋๋ค.
factory/AbstractFactory
public interface NoteBookSemiconductorFactory {
Cpu createCpu();
Ram createRam();
Storage createStorage();
Display createDisplay();
Os createOs();
}
factory/ConcreteFactory1
public class MacBookSemiconductorFactory implements NoteBookSemiconductorFactory {
@Override
public Cpu createCpu() {
return new AppleCpu("M1");
}
@Override
public Ram createRam() {
return new AppleRam("8GB");
}
@Override
public Storage createStorage() {
return new AppleStorage("HDD 250GB");
}
@Override
public Display createDisplay() {
return new AppleDisplay("Letina Display");
}
@Override
public Os createOs() {
return new MacOS("macOS");
}
}
๋งฅ๋ถ์ AppleCpu, AppleRam, … MacBook์ ๋ง๋ ๋ถํ๋ค์ ์์ฐํด๋ ๋๋ค.
factory/ConcreteFactory2
public class GalaxyBookSemiconductorFactory implements NoteBookSemiconductorFactory {
@Override
public Cpu createCpu() {
return new SamsungCpu("i-7700k");
}
@Override
public Ram createRam() {
return new SamsungRam("16GB");
}
@Override
public Storage createStorage() {
return new SamsungStorage("HDD 250GB");
}
@Override
public Display createDisplay() {
return new SamsungDisplay("LCD Display");
}
@Override
public Os createOs() {
return new WindowsOS("windowsOS");
}
}
๋ง์ฐฌ๊ฐ์ง๋ก GalaxyBook ์ ํ์ ๋ง๋ ๋ถํ๋ค์ ์์ฐํด๋ด๋๋ก ํฉ๋๋ค.
3.2 AbstractProduct
๊ฐ ๊ณต์ฅ์์ ๋ถํ์ ๋ง๋ค ๋, ์ด์จ๋ AppleCpu๋ SamsungCpu๋ ๊ฒฐ๊ตญ์๋ CPU์ ์ข ๋ฅ์ผ ๊ฒ์ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ฐ ๋ถํ๋ง๋ค ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ฌ ๊ฐ ์ ์กฐ์ฌ์์๋ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ํตํด ํ์ฅ์ด ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ก ์ค๊ณํ ์ ์์ต๋๋ค.
product/AbstractProduct
public interface Cpu {
}
product/concreteProduct1
public class AppleCpu implements Cpu {
private String name;
// getter, setter, ...
}
product/concreteProduct2
public class SamsungCpu implements Cpu {
private String name;
// getter, setter, ...
}
… ๋๋จธ์ง๋ค์ ์๋ต
3.3 NoteBook
๊ธฐ์กด ๋ ธํธ๋ถ์ ๋ถํ๋ค์ String์์ interface ํ์ ์ผ๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค. prepare()๋ผ๋ ๋ฉ์๋๋ฅผ ํตํด ์๋ธ ํด๋์ค์์ ์ด๋ค ๋ถํ๋ค์ ์จ์ผํ๋์ง์ ๋ํด์ ์์ํฉ๋๋ค. ์ค์ ํ๊ณ ํฌ์ฅํ๋ ์ผ์ ์ด๋ ๋ ธํธ๋ถ์ด๋ ๋์ผํ๋ ํ์์ ๋ฐ๋ผ ์ค๋ฒ๋ผ์ด๋ฉํ ์ ์์ต๋๋ค.
notebook/AbstractNoteBook
public abstract class NoteBook {
String name;
Cpu cpu;
Ram ram;
Storage storage;
Display display;
Os os;
public abstract void prepare();
public void setting() {
System.out.println("Setting NoteBook...");
}
public void box() {
System.out.println("Boxing NoteBook...");
}
}
notebook/MacBook
๊ฐ ๊ตฌ์ ํด๋์ค์๋ ๋ถํ๊ณต์ฅ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด์ ํด๋น ๋ ธํธ๋ถ์๋ ์ด๋ค ๋ถํ์ ์จ์ผํ๋์ง ์ผ์ผ์ด ์ํ์๊ฐ ์์ด์ก์ต๋๋ค.
public class MacBook extends NoteBook {
NoteBookSemiconductorFactory semiconductorFactory;
public MacBook(NoteBookSemiconductorFactory semiconductorFactory) {
this.semiconductorFactory = semiconductorFactory;
}
@Override
public void prepare() {
this.name = "MacBook";
this.cpu = semiconductorFactory.createCpu();
this.ram = semiconductorFactory.createRam();
this.storage = semiconductorFactory.createStorage();
this.display = semiconductorFactory.createDisplay();
this.os = semiconductorFactory.createOs();
}
@Override
public String toString() {
return "MacBook{" +
"name='" + name + '\\\\'' +
", cpu=" + cpu +
", ram=" + ram +
", storage=" + storage +
", display=" + display +
", os=" + os +
'}';
}
}
notebook/GalaxyBook
public class GalaxyBook extends NoteBook {
NoteBookSemiconductorFactory semiconductorFactory;
public GalaxyBook(NoteBookSemiconductorFactory semiconductorFactory) {
this.semiconductorFactory = semiconductorFactory;
}
@Override
public void prepare() {
this.name = "GalaxyBook";
this.cpu = semiconductorFactory.createCpu();
this.ram = semiconductorFactory.createRam();
this.storage = semiconductorFactory.createStorage();
this.display = semiconductorFactory.createDisplay();
this.os = semiconductorFactory.createOs();
}
@Override
public String toString() {
return "GalaxyBook{" +
"name='" + name + '\\\\'' +
", cpu=" + cpu +
", ram=" + ram +
", storage=" + storage +
", display=" + display +
", os=" + os +
'}';
}
}
3.4 Client
ํด๋ผ์ด์ธํธ ์ฝ๋ ์ ๋๋ค. ์ถ์ ํด๋์ค๋ก createNoteBook()์ด๋ผ๋ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ํด๋น ๋ฉ์๋๋ ์๋ธ ํด๋์ค์๊ฒ ๊ฐ์ฒด ์์ฑ ๋ถ๋ถ์ ์์ํ์ฌ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
public abstract class NoteBookStore {
public NoteBook orderNoteBook() {
NoteBook noteBook = createNoteBook();
noteBook.prepare();
noteBook.make();
noteBook.boxing();
return noteBook;
}
protected abstract NoteBook createNoteBook();
}
client/ConcreteClient1
์คํ ์ด๋ฅผ ์์ฑํ ๋ ์ ๋ฌ๋ฐ์ ๋ถํ๊ณต์ฅ์ ๊ฐ์ง๊ณ ๋ ธํธ๋ถ์ ์์ฑํ๊ฒ ๋ฉ๋๋ค. createNoteBook()์์๋ ์ด๋ค ๋ถํ์ ๊ฐ์ง๊ณ ์์ฑํ๋์ง์ ๋ํด์๋ ์์ง ๋ชปํฉ๋๋ค.
public class MacBookStore extends NoteBookStore {
NoteBookSemiconductorFactory factory;
public MacBookStore(NoteBookSemiconductorFactory factory) {
this.factory = factory;
}
@Override
protected NoteBook createNoteBook() {
return new MacBook(factory);
}
}
client/ConcreteClient2
public class GalaxyBookStore extends NoteBookStore {
NoteBookSemiconductorFactory factory;
public GalaxyBookStore(NoteBookSemiconductorFactory factory) {
this.factory = factory;
}
@Override
protected NoteBook createNoteBook() {
return new GalaxyBook(factory);
}
}
3.5 Main
์ค์ ๋ ธํธ๋ถ์ ๋ง๋ค์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
public class Main {
public static void main(String[] args) {
MacBookSemiconductorFactory macBookSemiconductorFactory = new MacBookSemiconductorFactory();
GalaxyBookSemiconductorFactory galaxyBookSemiconductorFactory = new GalaxyBookSemiconductorFactory();
MacBookStore macBookStore = new MacBookStore(macBookSemiconductorFactory);
GalaxyBookStore galaxyBookStore = new GalaxyBookStore(galaxyBookSemiconductorFactory);
NoteBook macBook = macBookStore.orderNoteBook();
System.out.println(macBook);
System.out.println("---------------------");
NoteBook galaxyBook = galaxyBookStore.orderNoteBook();
System.out.println(galaxyBook);
}
}
์คํ๊ฒฐ๊ณผ
Make NoteBook...
Boxing NoteBook...
MacBook{name='MacBook', cpu=AppleCpu{name='M1'}, ram=AppleRam{name='8GB'}, storage=AppleStorage{name='HDD 250GB'}, display=AppleDisplay{name='Letina Display'}, os=MacOS{name='macOS'}}
---------------------
Make NoteBook...
Boxing NoteBook...
GalaxyBook{name='GalaxyBook', cpu=SamsungCpu{name='i-7700k'}, ram=SamsungRam{name='16GB'}, storage=SamsungStorage{name='HDD 250GB'}, display=SamsungDisplay{name='LCD Display'}, os=WindowsOS{name='windowsOS'}}
์ ๋ฆฌ
์ถ์ ํฉํ ๋ฆฌ ํจํด์ ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด ์๋ก ์ฐ๊ด๋ ๊ตฌ์ ํด๋์ค๋ฅผ ์ง์ ํ์ง ์๊ณ ๋ ์์ฑํ ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ์ ํฉํ ๋ฆฌ์์ ์์ฐ๋๋ ์ ํ์ ๋ถ๋ฆฌ์์ผ ์ด๋ค ์ ํ์ด ์์ฑ๋๋์ง๋ ์ ํ ์ ํ์๊ฐ ์์ต๋๋ค.
๐ก ์ฅ์
- ๊ตฌ์ ์ ํ๋ค๊ณผ ํด๋ผ์ด์ธํธ ์ฝ๋ ์ฌ์ด์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถค
- ํฉํ ๋ฆฌ์์ ์์ฑ๋๋ ์ ํ๋ค์ ์ํธํธํ์ ๋ณด์ฅํ ์ ์์
- ๋จ์ผ ์ฑ ์ ์์น
- ๊ฐ๋ฐฉ/ํ์ ์์น
๐ก ๋จ์
- ํจํด์ ๊ตฌํํ๊ธฐ ์ํด ์๋ก์ด ์ธํฐํ์ด์ค๋ค์ด ๋ง์ด ์์ฑ๋๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์
- ์ธํฐํ์ด์ค๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ชจ๋ ํฉํ ๋ฆฌ์ ๋ํ ์ฝ๋ ์์ ์ด ํ์ํ๋ค.
REFERENCES