본문 바로가기

개발

디자인 패턴을 적용해보자 - 팩토리(2). (pizza 예제 아님)

1. 간단한 팩토리 적용


이전 포스팅에서는 팩토리를 적용하기 전 상황과 문제점에 대해서 이야기해보았다. 

이번 포스팅에서는 간단한 팩토리(simple factory) 를 적용해 보겠다.

 

간단한 팩토리 태그로 이동하여 코드를 확인해보자.

https://github.com/SongHae8640/designPatternApply

 

GitHub - SongHae8640/designPatternApply

Contribute to SongHae8640/designPatternApply development by creating an account on GitHub.

github.com

git checkout tags/factory_simple

 

우선 게시글, 음료 의 객체를 반환 및 댓글수 변경 작업을 하는 기능을 추상화하고 이를 상속받는 객체를 만들었다.

public interface TypesRepository {
    void checkTypesId(Long typesId);
    void addCommentCount(Long typesId);
}


@Component
@RequiredArgsConstructor
public class TypesDrinkRepository implements TypesRepository {
    private final DrinkRepository drinkRepository;

    @Override
    public void checkTypesId(Long typesId) {
        drinkRepository.findById(typesId)
                .orElseThrow(() -> new NoSuchElementException("존재하지 않는 음료입니다."));
    }

    @Override
    public void addCommentCount(Long typesId) {
        drinkRepository.findById(typesId)
                .orElseThrow(() -> new NoSuchElementException("존재하지 않는 음료입니다."))
                .addCommentCount();
    }
}

@Component
@RequiredArgsConstructor
public class TypesBoardRepository implements TypesRepository {

    private final BoardRepository boardRepository;

    @Override
    public void checkTypesId(Long typesId) {
        boardRepository.findById(typesId)
                .orElseThrow(() -> new NoSuchElementException("존재하지 않는 게시글입니다."));
    }

    @Override
    public void addCommentCount(Long typesId) {
        boardRepository.findById(typesId)
                .orElseThrow(() -> new NoSuchElementException("존재하지 않는 게시글입니다."))
                .addCommentCount();
    }
}

 

그리고 댓글타입별로 TypesRepository 를 반환하는 팩토리 객체를 만들고 이를 service에 적용하였다.

@Component
@RequiredArgsConstructor
public class RepositoryFactory {

    private final TypesDrinkRepository typesDrinkRepository;
    private final TypesBoardRepository typesBoardRepository;

    public TypesRepository getRepository(CommentType commentType) {
        if (commentType == CommentType.DRINK) {
            return typesDrinkRepository;
        } else if (commentType == CommentType.BOARD) {
            return typesBoardRepository;
        }
        throw new IllegalArgumentException("Invalid CommentType: " + commentType);
    }
}



@Service
@RequiredArgsConstructor
public class CommentService {

    private final CommentRepository commentRepository;
    private final RepositoryFactory repositoryFactory;


    public List<Comment> getCommentList(CommentType commentType, Long typesId) {
        repositoryFactory.getRepository(commentType)
                .checkTypesId(typesId);
        return commentRepository.findAllByCommentTypeAndTypesId(commentType, typesId);
    }

    public Comment saveComment(Comment comment) {
        repositoryFactory.getRepository(comment.getCommentType())
                .addCommentCount(comment.getTypesId());
        return commentRepository.save(comment);
    }
}

 

 

 

2. 테스트


코드는 수정되었지만 테스트 코드 작성을 미리 해둔 덕분에 정상적으로 조회 및 저장 된다는것을 확인할 수 있다.

 

 

 

 

 

 

 

3. UML 


 

 

출처 : 구글

SImple factory 의 UML로 설명하자면 아래와 같이 대응된다.

 

client = CommentSerivce

SimpleFactory = RepositoryFactory

Product = TypesRepository

ConcreteProduct1 = TypesBoardRepository

ConcreteProduct2 = TypesDrinkRepository

 

 

 

 

 

다음 포스팅에서는 팩토리 메서드 패턴을 이용하여 리펙토링 해보겠다.