Skip to content

Conversation

@asn6878
Copy link
Member

@asn6878 asn6878 commented Jan 7, 2025

📋 작업 내용

feed-crawler main 함수명 변경

기존의 runCrawler라는 네이밍보다는 main이 어울린다 생각하여 함수 명을 변경하였습니다.

DatabaseConnection 인터페이스 작성

의존성 주입 방식을 위해서는 사용중인 Connection 객체들을 추상화 하여야 합니다.
이에따라 DatabaseConnection 인터페이스를 생성하고, 사용할 수 있도록 처리하였습니다.

feed-crawler에 tsyringe를 활용한 DI Container 도입

import {mysqlConnection} from "../common/mysql-access";

export class FeedRepository {
  public async insertFeeds(resultData: FeedDetail[]) {
    const query = `
            INSERT INTO feed (blog_id, created_at, title, path, thumbnail)
            VALUES (?, ?, ?, ?, ?)
        `;

    const insertPromises = resultData.map(async (feed) => {
      return mysqlConnection.executeQuery(query, [ // 강한 결합
        feed.blogId,
        feed.pubDate,
        feed.title,
        feed.link,
        feed.imageUrl,
      ]);
    });

이러한 모듈끼리의 강결합은 OOP의 SOLID 원칙중 Dependency Inversion Principle에 위배되며, 테스트와 유지보수에 영향을 줍니다.

그리하여 의존성을 외부에서 주입해주고자 했고, 이를 위해 DI Container (tsyringe)를 사용하기로 했습니다.

  • tsyringe 인가요?
    tsyringe는 다른 NodeJS 진영 DI Container들 중 가벼운 편에 속하며, 커뮤니티가 가장 활성화 되어 있었습니다.
    (신뢰의 Microsoft)

  • 생성자 주입 방식 쓰지 왜 굳이 DI Container 썼나요?
    DI Container를 사용하면 개발자가 직접 객체 생성과 의존성 주입 코드를 수정할 일이 없습니다. 코드는 그대로 유지한 채 DI Container에 등록된 설정만 왔다 갔다 해주어 의존성을 손쉽게 관리할 수 있습니다.

// container.ts
container.register<DatabaseConnection>(DEPENDENCY_SYMBOLS.DatabaseConnection, {
    useValue: mysqlConnection // 만약 postgresqlConnection 이라는게 생기면, 여기서 useValue값을 변경하면 됩니다.
});
...

export { container };
async function main() {
  logger.info("==========작업 시작==========");
  const startTime = Date.now();

  // 아래와 같은 방법으로 DI Container에서 필요한 객체들을 가져옵니다.
  const rssRepository = container.resolve<RssRepository>(DEPENDENCY_SYMBOLS.RssRepository); // 문자열에 의존하지 않고, Symbol을 통해서 가져옵니다.
  const feedRepository = container.resolve<FeedRepository>(DEPENDENCY_SYMBOLS.FeedRepository);
  const dbConnection = container.resolve<DatabaseConnection>(DEPENDENCY_SYMBOLS.DatabaseConnection);

  const feedCrawler = new FeedCrawler(rssRepository, feedRepository); // DI Container에서 가져온 의존성을 주입해줍니다.
  await feedCrawler.start();

  const endTime = Date.now();
  const executionTime = endTime - startTime;

  await dbConnection.end();

📷 스크린 샷(선택 사항)

image

@asn6878 asn6878 added the 🔨 Refactor 리팩토링 (구조 변경) label Jan 7, 2025
@asn6878 asn6878 self-assigned this Jan 7, 2025
Copy link
Collaborator

@CodeVac513 CodeVac513 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고 많으셨습니다!
질문 사항 1개 남겼습니다.
그 외에 tsyringe를 찾아보니 typescript에서 호환이 잘 된다고 하더라고요.(역시 마소...)
거기에 가볍고 직관적인 편이라 하고요. (자료)
성윤님 덕에 라이브러리 하나 알아가는군요. ㅎㅎ

Copy link
Member

@Jo-Minseok Jo-Minseok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DI Container에 대해서 조금 감은 잡힌 느낌이네요 ㅎㅎ 덕분에 많이 배워갑니다.

@asn6878 asn6878 merged commit 2e9bf2c into main Jan 7, 2025
1 check passed
@asn6878 asn6878 deleted the refactor/feed-crawler-oop branch January 8, 2025 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 Refactor 리팩토링 (구조 변경)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants