카테고리 없음

파이썬 데일리코딩 - 팩토리 메소드 패턴

jssvs 2024. 11. 20. 23:58
반응형

 

오늘 다뤄볼 주제는 팩토리 메소드 패턴입니다.

 

이 디자인의 특징은 클라이언트 코드 수준에서 객체를 직접 생성하지 않고, 팩토리 메소드에게 위임합니다.

 

이렇게 하면 클라이언트 코드와 사용하는 객체간의 거리를 만들어 유연성과 유지관리성을 높일 수 있게 되는데, 이런 표현을 책에서는 loose coupling(느슨한 결합)이라고 합니다.

 

아래 팩토리 메소드 패턴의 주요 구성요소와 함께 예제코드를 작성해보겠습니다

 

 

구성 요소 

1) Generator = abstract class or interface 

2) SubClass of Generator = Product 유형의 오브젝트를 생성할 팩토리 메소드가 구현될 클래스

3) Product = abstract class or interface

4) SubClass of Product = 팩토리 메소드에 의해 생성되는 오브젝트의 클래스

 

 

 

 

예제 코드 설명

- (1)Generator 는 팩토리 메소드가 구현될 추상화 클래스이며, ABC 클래스를 상속받아 Base 클래스의 메소드의 구현을 강제화 합니다

- (2) SubClass 는 Generator 클래스를 상속받아, 유형별 데이터 수집기 클래스의 객체를 생성하는 팩토리 메소드를 구현합니다.

- (3) Product 는 데이터 수집기의 추상화 클래스입니다.

- (4) SubClass 는 Product 클래스를 상속받아, 유형별 데이터 수집기의 동작을 구현합니다.

- (5) create_collector 함수는 유형별 데이터 수집기의 객체를 생성하는 팩토리 메소드를 구현합니다.

 

 

예제 코드 

from abc import ABC, abstractmethod





class Collector(ABC):

    @abstractmethod

    def collect(self, data):

        pass







class DBCollector(Collector):

    def collect(self, data:str):

        print(f"Collecting data from database: {data}")





class APICollector(Collector):

    def collect(self, data:str):

        print(f"Collecting data from API: {data}")





class Generator(ABC):

    

    @abstractmethod

    def generate(self):

        pass



class DBCollectorGenerator(Generator):

    

    def generate(self):

        return DBCollector()

    

class APICollectorGenerator(Generator):



    def generate(self):

        return APICollector()

    



def create_collector(name:str):

    generator = {

        "db" : DBCollectorGenerator, 

        "api" : APICollectorGenerator

    }



    return generator[name]().generate()





def main():

    db_collector = create_collector("db")

    api_collector = create_collector("api")



    target_data = ["user_information","product_information"]



    for collecting_data in target_data:

        db_collector.collect(collecting_data)

        api_collector.collect(collecting_data)



if __name__ == "__main__":

    main()

 

 

출력 결과 

Collecting data from database: user_information

Collecting data from API: user_information

Collecting data from database: product_information

Collecting data from API: product_information

 

 

만약 제가 카카오 API 를 연동해서 어떤 데이터를 수집해야 하는 요구상황이 생긴다고 가정해볼게요. 

 

저는 위 구조에서 KaKaoAPICollector 클래스를 추가하고 collect 메소드를 구현할거에요.

 

기존 코드의 영향을 적게 주면서 새로운 클래스만 추가하면 되기 때문에, 이런 부분에서 유연성과 확장성이 올라갔다고도 볼 수 있을 겁니다.

 

 

.

 

 

 

반응형