A A
[Design Pattern] Factory Method Pattern - νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄

Factory Method Pattern

νŒ©ν† λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄μ€ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 방법을 μƒμœ„ 클래슀 μΈ‘μ—μ„œ κ²°μ •ν•˜μ§€λ§Œ, ꡬ체적인 μΈμŠ€ν„΄μŠ€μ˜ μœ ν˜•κΉŒμ§€λŠ” κ²°μ •ν•˜μ§€ μ•ŠλŠ” λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€.
λŒ€μ‹ , ꡬ체적인 λ‚΄μš©μ€ λͺ¨λ‘ ν•˜μœ„ 클래슀 μΈ‘μ—μ„œ μˆ˜ν–‰λ©λ‹ˆλ‹€. 이λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€ 생성을 μœ„ν•œ 골격과 μ‹€μ œ μΈμŠ€ν„΄μŠ€ μƒμ„±μ˜ 클래슀λ₯Ό λΆ„λ¦¬ν•˜μ—¬ 생각할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μƒμœ„ ν΄λž˜μŠ€μ—μ„œ μΈμŠ€ν„΄μŠ€ 생성 방법 κ²°μ •: μƒμœ„ ν΄λž˜μŠ€μ—μ„œλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ 좔상 λ©”μ„œλ“œ(νŒ©ν† λ¦¬ λ©”μ„œλ“œ)λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
    • 이 λ©”μ„œλ“œλŠ” μ‹€μ œλ‘œ μ–΄λ–€ μœ ν˜•μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할지 κ²°μ •ν•˜μ§€ μ•Šκ³ , κ·Έ 결정은 ν•˜μœ„ ν΄λž˜μŠ€μ— μœ„μž„λ©λ‹ˆλ‹€.
  • ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ ꡬ체적인 λ‚΄μš© μˆ˜ν–‰: μ‹€μ œ μΈμŠ€ν„΄μŠ€ 생성에 κ΄€λ ¨λœ ꡬ체적인 λ‘œμ§μ€ ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μˆ˜ν–‰λ©λ‹ˆλ‹€.
    • 각 ν•˜μœ„ ν΄λž˜μŠ€λŠ” μƒμœ„ ν΄λž˜μŠ€μ—μ„œ μ •μ˜λœ 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ—¬ ν•„μš”ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈλŠ” 직접적인 μΈμŠ€ν„΄μŠ€ 생성 과정에 λŒ€ν•΄ μ‹ κ²½ 쓰지 μ•ŠμŒ: ν΄λΌμ΄μ–ΈνŠΈλŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ›ν•˜λŠ” μœ ν˜•μ˜ 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
    • 이λ₯Ό 톡해 ν΄λΌμ΄μ–ΈνŠΈλŠ” μΈμŠ€ν„΄μŠ€ 생성에 λŒ€ν•œ λ³΅μž‘ν•œ μ„ΈλΆ€ λ‚΄μš©μ„ μ•Œ ν•„μš”κ°€ μ—†μœΌλ©°, λ‹¨μˆœνžˆ ν•„μš”ν•œ 객체λ₯Ό μš”μ²­ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ˜ν•œ μ‚¬μš©μžκ°€ μ˜€λΈŒμ νŠΈλ“€μ˜ 생성과정을 ν΄λΌμ΄μ–ΈνŠΈκ°€ 직접 λ‹€λ£° ν•„μš”κ°€ μ—†κ²Œ λ˜μ—ˆμœΌλ©°, 였브젝트의 λ³΅μž‘ν•œ 생성과정을 νŒ©ν† λ¦¬μ•ˆμ— μˆ¨κ²¨λ‘κ³  ν΄λΌμ΄μ–ΈνŠΈλŠ”νŠΉμ • μ œν’ˆλ§Œ λ§Œλ“€μ–΄μ£Όμ„Έμš”ν•˜λ©΄ ν•„μš”ν•œ 였브젝트만 λ§Œλ“€μ–΄μ„œ λ¦¬ν„΄ν•΄μ€€λ‹€λŠ” κ°œλ…μž…λ‹ˆλ‹€.
Factory Pattern은 Factory Method Pattern, Singleton Pattern, Builder pattern μ—μ„œ μ‘μš©μ΄ λ©λ‹ˆλ‹€.

Class Diagram


Simple Factory Pattern

  • 이 글에 Simple Factory Pattern에 λ°ν•˜μ—¬ μ„€λͺ…ν•΄ λ†“μ•˜μœΌλ‹ˆ μ°Έκ³ ν•΄μ£Όμ„Έμš”!
 

[Design Pattern] Factory Pattern

Creation Design Pattern (생성 λ””μžμΈ νŒ¨ν„΄) 생성 λ””μžμΈ νŒ¨ν„΄μ€ 객체 생성에 κ΄€λ ¨λœ λ””μžμΈ νŒ¨ν„΄μ„ λ§ν•©λ‹ˆλ‹€. 이 νŒ¨ν„΄λ“€μ€ 객체의 생성 과정을 μΊ‘μŠν™”ν•˜μ—¬, 객체 생성을 더 μœ μ—°ν•˜κ²Œ λ§Œλ“€μ–΄ μ€λ‹ˆλ‹€.

daehyun-bigbread.tistory.com


Factory Method Pattern

λ™μΌν•œ μΈν„°λ² μ΄μŠ€λ₯Ό μ΄μš©ν•œ κ°„κ²°ν•œ μ½”λ“œ μ˜ˆμ‹œ μž…λ‹ˆλ‹€.
# μ°¨λŸ‰ μΈν„°νŽ˜μ΄μŠ€
class Vehicle:
	def drive(self):
		return "car driving"

# ꡬ체적인 μ°¨λŸ‰ 클래슀
class Car(Vehicle):
    def drive(self):
        return "car driving"
	
class Truck(Vehicle):
	def drive(self):
       return "truck driving"

class Motorcycle(Vehicle):
    def drive(self):
       return "motorcycle zooming"
# νŒ©ν† λ¦¬ μΈν„°νŽ˜μ΄μŠ€
class VehicleFactory:
    def create_vehicle(self):
        pass

# ꡬ체적인 νŒ©ν† λ¦¬ 클래슀
class CarFactory(VehicleFactory):
    def create_vehicle(self):
        return Car()

class TruckFactory(VehicleFactory):
    def create_vehicle(self):
        return Truck()

class MotorcycleFactory(VehicleFactory):
    def create_vehicle(self):
        return Motorcycle()
# μ‚¬μš© μ˜ˆμ‹œ
def client_code(factory: VehicleFactory):
    vehicle = factory.create_vehicle()
    print(vehicle.drive())

car_factory = CarFactory()
client_code(car_factory)

truck_factory = TruckFactory()
client_code(truck_factory)

motorcycle_factory = MotorcycleFactory()
client_code(motorcycle_factory)

 

νŠΉν™”λœ κΈ°λŠ₯을 κ°€μ§€λŠ” μ—¬λŸ¬ μ œν’ˆμ„ μƒμ‚°ν•˜λŠ” 곡μž₯ μ½”λ“œ μ˜ˆμ‹œμž…λ‹ˆλ‹€.
# Robot Interface
class Robot:
	def speak(self):
		pass
	
class Cat(Robot):
	def speak(self):
        print("Meow")

class Dog(Robot):
    def speak(self):
        print("Bark")
# Factory Interface
class Factory():
    def createRobot(self):
        pass

class CatFactory(Factory):
    def _init_(self):
        self.cat_count = 0
    
    def createRobot(self):
        self.cat_count += 1
        return Cat()
    
    def catCount(self):
        return self.cat_count

class DogFactory(Factory):
    def haveDog(self):
        self.dog = self.,createRobot()
    
    def createRobot(self):
        return Dog()
    
    def addWing(self, dog:Dog):
        print("dog wings added")
        return dog
# μ‚¬μš© μ˜ˆμ‹œ
cat_factory = CatFactory()
cat1 = cat_factory.createRobot()
cat2 = cat_factory.createRobot()
print(cat_factory.catCount())

dog_factory = DogFactory()
dog1 = dog_factory.createRobot()
dog_Factory.addWing(dog1)

Factory Method Pattern (IDμΉ΄λ“œ λ°œκΈ‰ μ˜ˆμ‹œ)

  • Class Diagram


Implementation - Abstract Class

class Product:
	def use(self):
		pass
  • μ œν’ˆμ„ ν‘œν˜„ν•œ 클래슀, 좔상 Method use만이 μ„ μ–Έλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬κΈ°μ„œ ꡬ체적인 useλŠ” ꡬ체 ν΄λž˜μŠ€μ—κ²Œ λ§‘κΉλ‹ˆλ‹€.
  • μ—¬κΈ°μ„œ μ œν’ˆμ΄λž€? ‘무엇이든 useν•  수 μžˆλŠ”κ²ƒμœΌλ‘œ κ·œμ •ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
class Factory:
    def create(self, owner) -> Product:
        p = self.create_product(owner)
        self.register_product(p)
        return p

# ν•˜μœ„μ—μ„œ κ΅¬ν˜„λ¨
def create_product(self, owner) -> Product:
    pass

# ν•˜μœ„μ—μ„œ κ΅¬ν˜„λ¨
def register_product(self, product) -> None:
    pass
  • μ œν’ˆμ„ λ§Œλ“€κ³  (createProduct), λ§Œλ“  μ œν’ˆμ„ 등둝 (registerProduct)ν•©λ‹ˆλ‹€.
  • μ‹€μ§ˆμ μœΌλ‘œ μ œν’ˆμ„ λ§Œλ“€κ³ , λ“±λ‘ν•˜λŠ” ꡬ체적인 λ‚΄μš©μ€ ν•˜μœ„ν΄λž˜μŠ€μ—μ„œ μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  • CreateMethod μ—μ„œ μ œν’ˆμ„ λ§Œλ“€μ–΄μ„œ λ“±λ‘ν•œλ‹€λŠ” μˆœμ„œλ‘œ κ΅¬ν˜„λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • ꡬ체적인 λ‚΄μš©μ€ Factory Method Pattern을 μ μš©ν•œ ν”„λ‘œκ·Έλž¨μ— 따라 λ‹€λ¦…λ‹ˆλ‹€.

Concrete Class

class IDCard(Product):
    def __init__(self, owner):
        print(owner + "의 μΉ΄λ“œλ₯Ό λ§Œλ“­λ‹ˆλ‹€.")
        self.owner = owner

    def use(self):
        print(self.owner + "의 μΉ΄λ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.")
    
    def getOwner(self):
        return self.owner
  • 예둜써 μΈμ‹μΉ΄λ“œ 번호λ₯Ό λ‚˜νƒ€λ‚΄λŠ” IDCard 클래슀λ₯Ό 생각해 볼수 μžˆμŠ΅λ‹ˆλ‹€.
  • Product 클래슀의 ν•˜μœ„ 클래슀둜 μ •μ˜ν•©λ‹ˆλ‹€.
class IDCardFactory(Factory):
    def __init__(self):
        self.owners = [] # μΉ΄λ“œ λ°œκΈ‰μž 리슀트

    def create_product(self, owner) -> Product: # abstract method
        return IDCard(owner)

    def register_product(self, product):  # abstract method
        self.owners.append(product.getOwner())

    def getOwners(self):
        return self.owners
  • CreateProduct, RegisterProduct의 두가지 Methodλ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

Client

factory = IDCardFactory()
card1 = factory.create("홍길동")
card2 = factory.create("μ΄μˆœμ‹ ")
card3 = factory.create("강감찬")
card1.use()
card2.use()
card3.use()

Output

ν™κΈΈλ™μ˜ μΉ΄λ“œλ₯Ό λ§Œλ“­λ‹ˆλ‹€.
μ΄μˆœμ‹ μ˜ μΉ΄λ“œλ₯Ό λ§Œλ“­λ‹ˆλ‹€.
κ°•κ°μ°¬μ˜ μΉ΄λ“œλ₯Ό λ§Œλ“­λ‹ˆλ‹€.
ν™κΈΈλ™μ˜ μΉ΄λ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
μ΄μˆœμ‹ μ˜ μΉ΄λ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
κ°•κ°μ°¬μ˜ μΉ΄λ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

Summary of Factory Method Pattern

  • Factory Method Pattern은 Factory Pattern의 ν™•μž₯λ²„μ „μž…λ‹ˆλ‹€.
  • Factory μžμ²΄μ— μ—¬λŸ¬ κΈ°λŠ₯을 μΆ”κ°€ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
πŸ’‘ 예λ₯Ό λ“€μ–΄, Aμ œν’ˆκ³Ό Bμ œν’ˆμ„ λͺ‡κ°œλ₯Ό λ§Œλ“€μ—ˆλŠ”μ§€ μΆ”μ ν•˜κ³  싢을 μˆ˜λ„ 있고, Factory의 μƒνƒœλ₯Ό μ•Œκ³  μ‹Άμ„μˆ˜λ„ 있고, Factoryμ—μ„œ μƒμ„±λ˜λŠ” 였브젝트λ₯Ό μΆ”κ°€μ μœΌλ‘œ μ²˜λ¦¬ν•΄μ•Όν•  일이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
이럴 λ•Œ λ‹¨μˆœν•œ κΈ°μ€€ Factory Patternλ§ŒμœΌλ‘œλŠ” μΆ”κ°€ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ”λ° 어렀움이 μžˆμŠ΅λ‹ˆλ‹€. → κ·Έλž˜μ„œ Factory Method Pattern이 λ“±μž₯ν•©λ‹ˆλ‹€.
  • Factory Interfaceλ₯Ό λ”°λ‘œ 두어 각 μ œν’ˆμ— νŠΉν™”λœ Factory듀을 λ§Œλ“€μ–΄μ„œ νŠΉν™”λœ Factory에 μ—¬λŸ¬ κΈ°λŠ₯듀을 μΆ”κ°€ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
  • Framework의 λ‚΄μš©μ„ μˆ˜μ •ν•˜μ§€ μ•Šμ•„λ„ μ „ν˜€ λ‹€λ₯Έ μ œν’ˆκ³Ό 곡μž₯을 λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 즉, framework λ‚΄μš©μ„ μˆ˜μ •ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
  • 우리의 μ˜ˆμ‹œμ—μ„œ framework νŒ¨ν‚€μ§€λŠ” idcard νŒ¨ν‚€μ§€μ— “μ˜μ‘΄ν•˜κ³  μžˆμ§€ μ•Šλ‹€”κ³  ν‘œν˜„ν•©λ‹ˆλ‹€.

νŒ¨ν„΄ 이용과 개발자 κ°„μ˜ μ˜μ‚¬μ†Œν†΅

  • μ‹€μ œλ‘œ μ΄λ£¨μ–΄μ§€λŠ” μ‘°μž‘μ— λΉ„ν•˜μ—¬ λ³΅μž‘ν•œ ν”„λ‘œκ·Έλž¨μœΌλ‘œ λŠκ»΄μ§ˆμˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 1개의 클래슀λ₯Ό μ½λŠ”κ²ƒλ§ŒμœΌλ‘œλ„ λ™μž‘μ„ μ΄ν•΄ν•˜κΈ° μ–΄λ ΅κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
  • μƒμœ„ ν΄λž˜μŠ€μ—μ„œ λ™μž‘μ˜ 골격을 μ΄ν•΄ν•˜κ³ , κ±°κΈ°μ—μ„œ μ‚¬μš©λ˜κ³  μžˆλŠ” 좔상 Methodκ°€ 무엇인지 확인 ν›„, κ·Έ 좔상 Methodλ₯Ό μ‹€μ œλ‘œ κ΅¬ν˜„ν•˜κ³  μžˆλŠ” 클래슀의 μ†ŒμŠ€μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³Ό ν•„μš”κ°€ μžˆμŠ΅λ‹ˆλ‹€.
  • 일반적으둜 λ””μžμΈ νŒ¨ν„΄μ„ μ‚¬μš©ν•΄μ„œ μ–΄λ–€ 클래슀λ₯Ό 섀계할 λ•Œ, κ·Έ 클래슀λ₯Ό 보수 ν•˜λŠ” μ‚¬λžŒμ—κ²Œ μ„€κ³„μžκ°€ μ˜λ„ν•œ λ””μžμΈ νŒ¨ν„΄μ΄ 무엇인지λ₯Ό 전달할 ν•„μš”κ°€ μžˆμŠ΅λ‹ˆλ‹€.
  • 그렇지 μ•ŠμœΌλ©΄? μ„€κ³„μžμ˜ 처음 μ˜λ„μ™€ 동떨어진 μˆ˜μ •μ΄ κ°€ν•΄μ§ˆ κ°€λŠ₯성이 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.
  • ν”„λ‘œκ·Έλž¨μ˜ μ£Όμ„μ΄λ‚˜ 개발 λ¬Έμ„œ μ•ˆμ— μ‹€μ œλ‘œ μ‚¬μš©λ˜κ³  μžˆλŠ” λ””μžμΈνŒ¨ν„΄μ˜ λͺ…μΉ­ & μ˜λ„λ₯Ό κΈ°μˆ ν•΄ λ†“λŠ”κ²ƒλ„ 쒋은 λ°©λ²•μž…λ‹ˆλ‹€.