본문 바로가기
책/클린코드

[클린코드 완독하기] Chapter 08 모호한 경계를 구분짓기

by 6161990 2021. 9. 29.

Chapter 08. 모호한 경계를 구분짓기

01 경계 

 

  • 오픈소스, 라이브러리를 안쓰는 프로젝트는 없다.
  • 우리가 만든 코드에 외부에서 들어온 코드를 병합해야한다.
  • 외부 코드는 외부에서 만든 코드인데, 외부 시스템과 호출하거나 단순히 외부에서 만들어진 코드일 수 있다. 
  • 우리 코드와 외부 코드를 깔끔하게 통합시키기 위해 경계를 잘 지어야 한다.

 

 

02 경계 짓기 (1) 우리 코드를 보호하기

캡슐화 (Encapsulation)

📍 객체의 실체 구현을 외부로부터 감추는 방식

 

📍 Sensor를 관리해야 한다. Sensor는 외부에서 사용된다.

  • Sensor Id와 Sensor 객체로 저장하고 싶어서, Map을 사용한다.
  • 하지만 Map을 그대로 사용하면 Map이 가진 clear()가 외부로 노출된다. 
  • Sensor의 '외부'코드 관점에서 Sensor 객체의 값들만 가져오고 싶다.

🤚 캡슐화를 한다 !

👎 Bad
Map<Sensor> sensors = new HashMap<Sensor>( );
Sensor s = sensors.get(sensorId);
  • Map 인터페이스가 제공하는 clear 등 불필요한 기능이 노출된다. 
  • Map이 반환하는 Object 를 올바른 유형으로 변환할 책임은 Map을 사용하는 클라이언트에 있다.
  • 외부 코드가 함부로 노출하면 sensor 데이터가 손상될 수 있고, 이는 의도와 벗어난다. 

 

👍 Good
public class Sensor 
{
    private Map<Sensor> sensors = new HashMap<Sensor>( );
 
    public Sensor getById(String sensorId) {
         return sensors.get(sensorId);
    } 
}
  • 캡슐화를 통해 Map을 감춘다.
  • 원하는 기능만 공개할 수 있다.
  • 적절한 경계로 우리 코드를 보호할 수 있다.
  • Map과 같은 경계 인터페이스를 이용할 때는 이를 이용하는 클래스나 클래스 계열 밖으로 노출되지 않도록 주의한다. 

 

 

03 경계 짓기 (2) 외부 코드와 호환하기

어뎁터패턴 (Adapter Pattern) 

📍 외부 코드를 호출 할 때, 우리가 정의한 인터페이스 대로 호출하기 위해 사용하는 패턴

 

🤚 Adapter 패턴 in Elastic Search

NettyAdapter

  • 11번 ~ 18번 라인 우리 코드(내 패키지)가 아닌 외부 코드를 import하고 있다.
  • 외부 코드인 NettyAdaptor는 nettyChannel을 감싸고 있다. 

 

Adapter인 NettyAdaptor와 Client인 HttpReadWriteHandler

  • 우리가 원하는 방식인 read할 때 ByteBuffer[]로 parameter를 보내면, 외부 코드인 nettyChannel에 ByteBuf 타입으로 parameter를 변환하여 전달한다. 
  • Page[]타입 parameter로도 전달할 수 있다. Adapter에 메서드를 추가해 우리가 원하는 타입의 파라미터를 전달할 수 있다. 
  • 만약 adapter를 통한 변환을 거치지 않았다면 nettyChannel에 데이터를 전달할 때마다 타입을 변환하는 과정이 필요했고, 이는 중복을 발생시켰을 것이다. 

 

 

04 외부 라이브러리 테스트하기 - Learning Test

📍 Learning Test를 작성해 라이브러리를 테스트한다.

 

🤚이미 거기서 테스트를 하지 않았을까? 근데 라이브러리를 '사용'하는 내가 테스트를?

 

  • 학습 테스트는 이해도를 높인다.
  • * 학습 테스트 : 곧바로 우리쪽 코드를 작성해 외부 코드를 호출하는 태신 먼저 간단한 테스트 케이스를 작성해 외부 코드를 익히는 방식
  • 외부 코드의 버전이 변경됐을 때, 우리 코드와 호환되는지 확인할 수 있다.