[CLEAN CODE] 경계(Boundaries)

rami·2021년 7월 3일
0

clean-code

목록 보기
8/15
post-thumbnail

외부 코드를 깔끔하게 통합할 수 있는 '경계'를 깔끔하게 처리하는 기법과 기교를 살펴보자.

외부 코드 사용하기

Using Third-Party Code

인터페이스 제공자는 적용성을 최대한 넓히려 하고,
인터페이스 사용자는 자신의 요구에 집중한다.

java.util.Map 사용 예시

1️⃣ sensors라는 객체를 담는 Map 생성

Map sensors = new HashMap();
Sensor s = (Sensor)sensors.get(sensorId);
  • Map이 반환하는 Object를 올바른 유형으로 변환할 책임은 Map을 사용하는 클라이언트에 있고, 의도도 분명하지 않는다.

2️⃣ 제네릭스 사용

    Map<String, Sensor> sensors = new HashMap<Sensor>();
    Sensor s = sensors.get(sensorId);
  • Map<String, Sensor>가 사용자에게 필요하지 않는 기능까지 제공한다는 문제는 해결하지 못하고, 해당 인스턴스를 여기저기로 넘긴다면, Map 인터페이스가 변할 경우 수정할 코드가 상당히 많아진다.

3️⃣ Map을 좀 더 깔끔하게 사용

public class Sensors {
	private Map sensors = new HashMap();
	
	public Sensor getById(String id) {
		return (Sensor) sensors.get(id);
	}
	
	// 이하 생략
}
  • 경계 인터페이스인 Map을 Sensors 안으로 숨겨서 Map 인터페이스가 변하더라도 나머지 프로그램에는 영향을 미치지 않는다.
  • 제네릭스가 사용되었는지 여부에 신결 쓸 필요가 없다.

✔ Map과 같은 경계 인터페이스를 이용할 때는 이를 이용하는 클래스나 클래스 계열 밖으로 노출되지 않도록 주의한다.

✔ Map 인스턴스를 공개 API의 인수로 넘기거나 반환값으로 사용하지 않는다.

경계 살피고 익히기

Exploring and Learning Boundaries

  • 외부 코드를 익히고, 외부 코드를 통합하기는 어렵다.
  • 곧장 외부 코드를 호출하는 대신 외부 코드를 익히는 학습 테스트를 하는 것을 권한다.
  • 학습 테스트는 프로그램에서 사용하려는 방식대로 외부 API를 호출해서 제대로 이해하는지를 확인하는 것이다.

log4j 익히기

Learning log4j

public class LogTest {
    private Logger logger;
    
    @Before
    public void initialize() {
        logger = Logger.getLogger("logger");
        logger.removeAllAppenders();
        Logger.getRootLogger().removeAllAppenders();
    }
    
    @Test
    public void basicLogger() {
        BasicConfigurator.configure();
        logger.info("basicLogger");
    }
    
    @Test
    public void addAppenderWithStream() {
        logger.addAppender(new ConsoleAppender(new ParrenLayout("%p %t %m%n"), ConsoleAppender.SYSTEM_OUT));
        logger.info("addAppenderWithStream");
    }
    
    @Test
    public void addAppenderWithoutStream() {
        logger.addAppender(new ConsoleAppender(new PatternLayout("%p %t %m%n")));
        logger.intfo("addAppenderWithoutStream");
    }
}

학습 테스트는 공짜 이상이다

Learning Tests Are Better Than Free

  • 학습 테스트는 필요한 지식만 확보하는 손쉬운 방법이며, 이해도를 높여주는 정확한 실험이다.
  • 학습 테스트를 이용하면 패키지의 새 버전으로 이전하기 쉬우나, 그렇지 않다면 낡은 버전을 필요 이상으로 오래 사용하려는 유혹에 빠진다.

아직 존재하지 않는 코드를 사용하기

Using Code That Does Not Yet Exist

  • 때때로 설계조차 되지 않은 모듈과 연계되어 개발을 해야할 수도 있다.
  • 이 때, 자체적으로 인터페이스를 정의하고 어댑터 패턴으로 API 사용을 캡슐화해 API가 바뀔 때 수정할 코드를 한 곳으로 모으는 방법이 있을 수 있다.

깨끗한 경계

Clean Boundaries

  • 변경을 통제하지 못하는 코드를 사용할 때는 변경 비용이 커지지 않도록 각별히 주의한다.
  • 경계에 위치한 코드는 깔끔히 분리한다. 또한, 기대치를 정의하는 테스트 케이스도 작성한다.
  • 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자.
  • 새로운 클래스로 경계를 감싸거나, ADAPTER 패턴을 사용해 변경에 유연하게 대응한다.

📖 느낀점
Map을 쓸 때 java에서 제공하는 Map 인터페이스가 바뀔거라는 생각을 해본 적이 없었다.
너무 당연하게 항상 같게 제공할거라는 안일한 생각을 하고 있었다는 점에서 반성을 하게 되었다.
경계 인터페이스를 이용할 때 Wrapper 클래스 안에 숨기는 것은 앞으로 구현할 때 큰 도움이 될 것 같다.

profile
Developer

0개의 댓글