[DEV] 의존성과 아키텍쳐 (feat. DI , AOP)

2022. 6. 20. 15:41카테고리 없음

* 현성님 주관적인 방법론

 

- 의존성 

얼마나 A와 B가 의존해있냐.

 

의존성을 없애기 위해 아키텍처 적으로 해결하려는 방법

 

좋은 아키텍처란?

좋은 아키텍처? 라는 조건은 다양하고 사람마다 다를 수 있다. 

하지만, 모듈을 잘 분리해서 각 모듈간에 의존성을 줄이는 것이 좋은 아키텍처의 조건중에 하나라는 것은 많은 사람이 동의할 것.

 

 

의존성의 문제

 

- 간단한 기능 수정을 하려면 전체 코드를 이해햐야함

담당 기능 개발자가 변경된 경우

전체 코드를 이해하기 전까지 코드를 수정하기 어렵다. 

 

 - 테스트의 난이도가 높아진다.

간단한 기능 수정하려해도, 프로덕트 전체 기능을 테스트

 

의존성을 낮추기 위한 방법들

- 상황에 따른 적절한 디자인 패턴을 사용


- 인터페이스를 사용
   (코드가 들어나는 단점도 있음..모든 코드에 대해 다 interface를 만드는건 단점이 될 수도 있음)


- DI (Dependency Injection)을 사용함


- AOP(Aspect Oriented Programming)를 적절히 사용한다.

(AOP의 방향성이 의존성을 줄이기에 좋아서 작성)

 

 

 DI (Dependency Injection)

싱글톤 패턴은 클래스의 중복 생성 가능성을 해결해주긴 하지만 TDD에 어렵다는 단점이 있음. - testable한 코드가 될 수 없다.

JAVA Back으로 하면 spring에서 DI를 해주지만, JS에서는 DI에 대한 도구가 많이 없어 싱글톤 패턴을 많이 사용하는 경우가 많음.

 

 

 

DI를 생성한 경우 (TypeDI 라이브러리를 사용한 ts코드)

- testable한 코드가 됨

- 객체 생성에 대해 생각할 필요가 없다.

@Service()
class NetworkService {
  // ...
}

@Service()
class Serializer {
  // ...
}

@Service()
class NetworkConnector {
  // ...
}

Contianer.get(NetworkService).sendRequest(...)

DI를 사용할 경우 단점도 있음.

- 생성시 객체는 넣어주지만 param을 넣어주고 싶을 때가 있는데 이런 경우에 조금 어렵다. '

 

 

AOP (비지니스 로직에만 관심을 가지고 싶다)

비지니스 로직과 그 외의 로직을 분리

--> 그 외의 로직?  DB 커넥션 연결, 로깅, ETC 

express의 미들웨어나 axios의 interceptor로 신경쓰지 않고 걸어주지 않는 느낌? 

 

캐싱은 비지니스 로직이랑 관련 없으면

- 캐싱키를 생성하는 로직이 있으면, 로직 자체는 캐싱과 상관 없이 작성하고 있고

- 캐싱 Decorator에 대한 구현은 다른 개발자가 하면 된다. 

 

class NewsService {
  constructor(
    private readonly complexApi: ComplexApi,
    private readonly cache: Cache
  ) {}
  
  @Caching((lng: number, lat: number) => ["NEWS", lng.toString(), lat.toString()].join("::"))
  async getNews(
    date:number
  ): Promise<[...]> {
    return await newsService.getNews(date);
  }
}