layout: post title: 크롤러 설계 1편 [팩토리메서드] categories: [dev] author: 문재범 email: [email protected] date: 2021-10-30 tag:
<!-- @format -->
이번에 특정 게시판의 내용을 자동으로 스크랩해오는 기능을 추가하는 작업을 맡게 되었다. 사람이 수동으로 수행하는 작업을 프로그램으로 대체하게 하는 것이 프로젝트의 목표였다
코드를 작성하다보니 게시판의 스크랩을 수행하는 부분은 게시판의 종류에 따라 동작 방식 달라야 했다. 즉 게시판의 종류가 동작 방식을 결정하는 형태가 되어야 했다.
스크랩하는 기능을 수행하는 객체의 인터페이스를 미리 정의하고, 스크랩 기능이 실행되는 시점에 게시판의 유형을 판단해서 적절한 인스턴스가 생성된다면, 각 게시판에 따라 다른 방식으로 동작을 수행 할 것이다.
이럴때 사용가능한 디자인 패턴이 바로 팩토리 메서드이다. 어떤 서브클래스를 생성해야 하는지에 대한 정보를 캡슐화해서, 프로그램에서 분리하는 것이다. 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측 할 수 없을 때 팩토리 메서드를 사용할 수 있다. Creator는 어떤 객체가 생성될지 알 수 없다. 서브클래스에서 구현된 FactoryMethod 가 그역할을 수행한다. FactoryMethod를 사용함으로써 Product(여기에선 Scrapper에 해당) 클래스에 정의된 인터페이스와만 동작하도록 코드가 만들어지기 떄문에, 사용자가 정의한 어떤 구현클래스와도 동작 할 수 있게 된다.
팩토리 메서드를 통해서 객체를 생성하는 것이 객체에 직접 생성하는 것보다 응용성이 훨씬 높아질 수 있다. 예를 들어서 현재 스크래퍼는 특정 시간에 자동으로 수집기능을 수행할 것이다. 그런데, 사용자가 즉시 실행하는 테스트 스크랩기능이 추가된다고 가정해보자, 객체 별로 다른 버전을 제공하는 훅을 서브클래스(ConcreteCreator)에 정의해서 해결 할 수 있다.
팩토리메서드의 팩토리를 구현할 때는 2가지 방식이 있는데 하나는 인터페이스만 정의하고 구현을 서브클래스에 모두 위임하는 방법이 있고, 팩토리를 구체 클래스로 선언하고 바로 팩토리 메서드를 구현하는 방식이다. 나는 두 번째 방식으로 구현했다.
이런식으로 시스템을 구현하다보니 스크래퍼의 인터페이스의 서브클래스들의 코드가 상당부분 중복되는 문제가 발생했다. 이 문제에 대한 해결법은 다음글에서 담아보겠다.