경계

김태완·2023년 5월 7일
0

독서 스터디

목록 보기
4/8

외부코드를 사용할때 우리 코드와 깔끔하게 통합하는 방법에 대해 알아보자

우리는 종종 외부 코드(ex라이브러리)를 사용하면서 우리의 코드와 외부 코드간의 경계에서 복잡한 상황 또는 에러에 봉착한다.

캡슐화

책에서 Map인터페이스의 예시를 들었는데 Map을 여기저기에 보내어 쓴다면
clear를 해버리거나 의도치않은 객체를 반환해버리는 등 이슈가 발생한다.
또한 여기저기로 Map을 보내었을때 만약 Map 인터페이스가 변경된다면 수정 할 코드량이 매우 많아진다.

따라서 책에서는 이를 Sensor 클래스 내부로 캡슐화하여 Map인터페이스의 경계를 숨긴다.

class Sensors {
	private Map sensors = new HashMap();
    
    public Sensor getById(String id){
    	return (Seosor) sensors.get(id)
    }
}

단, 매번 캡슐화를 하기보단 map을 여기저기 class 밖으로 넘기지 말라는뜻.

학습 테스트

외부패키지 테스트는 우리 책임이 아니다. 하지만 우리가 사용할 코드를 테스트하는것이 바람직하다.

학습테스트란, 간단한 테스트 케이스를 먼저 작성하여 외부 코드를 익히는 방법이다.
즉 통제된 환경에서 api가 잘 작동하는지 이해하는 방식이다.
학습테스트는 투자대비 성과가 더 큰편.

Log4j 예시로 학습테스트

  1. 문서를 자세히 읽기전, 간단한 테스트 작성
public void testLog(){
	Logger logger = Logger.getLogger("MyLogger")
	logger.info("hellow")
}
  1. Appender라는 뭔가가 필요하다는 오류를 발견. -> 문서를 읽어 COnsoleAppender라는 클래스가 필요함을 인지
	public void testLogAppender(){
      Logger logger = Logger.getLogger("MyLogger")
      ConsoleAppender = appender = new ConsoleAppender(); // 추가
      logger.addAppender(appender) // 추가
      logger.info("hellow")
    }
  1. Appender에 출력 스트림이 없다는것을 발견.
public void testLogAddAppender(){
	Logger logger = Logger.getLogger("MyLogger")
    logger.removeAllAppenders();
    logger.addAppender(
    	new ConosleAppender(
        	new PatternLayout("%p, %t %m%n"),
            ConsoleAppender.SYSTEM_OUT
        )
    )
    logger.info("hellow")
}
  1. 이제 출력되는것을 확인.했으나 ConsoleAppender에 콘솔을 쓰라고 알리는게 이상함. 따라서 더 알아보니 ConsoleAppender는 "설정되지 않은상태"임을 인지.
  • 학습테스트는 필요한 지식만 확보하는 손쉬운 방법
  • 이해도를 높여주는 정확한 실험이다.
  • 패키지의 버전이 바뀌어 내 코드와 호환되지 않게 바뀌었더라도, 학습테스트가 이를 밝혀냄
  • 이런 경계테스트가 있다면 패키지의 새 버전으로의 이전도 용이해짐.

아는코드와 모르는 코드의 경계

때로는 이해할수없는 코드가있다(내 지식수준 밖의 내용) 책에선 이를 "송신기"라는 시스템이 이에 해당하는데,

이럴땐
1. 우리가 자체적으로 인터페이스(송신기에서 주는 주파수와 자료스트림을 입력으로 하는)를 정의한다. 그러면 이 인터페이스에 한해서 우리에게 아주 높은 코드 의도와 가독성을 가질수있다.
2. 이해할수 없는 코드(송신기)측의 api를 정의한 후에 1의 인터페이스와의 간극을 줄인다.
이때 Adapter 패턴으로 api사용을 캡슐화 한다

Adapter pattern
한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환한다.

https://jusungpark.tistory.com/22

깨끗한 경계

우수한 설계의 소프트웨어라면 버전이 변경되더라도 많은 재작업 시간, 노력이 요구되지 않는다.
경계의 위치에선 코드를 깔끔히 분리하고, 테스트 케이스를 잘 정의한다면 외부 패키지의 내용을 세세히 알 필요가 없다.

"송신기"예시처럼 외부코드에 의존하는 대신에 우리 코드에 의존하도록 코드를 짜는것이 중요하다

의존성 역전의 원칙

객체지향 5대 원칙인 SOLID중 하나.
고수준의 모듈이 저수준의 모듈을 의존해선 안된다는 원칙.

  • 고수준 모듈 : interface, 추상 클래스
  • 저수준 모듈 : 메인클래스, 객체

아래 링크의 예시를 보면,
기존에 KidRobot, Leg등의 장난감 class들에 의존하여, 장난감을 추가할때마다 Kid 클래스를 수정해야했지만

Toy라는 클래스에 장난감들을 의존시키고,
Kid는 Toy하나의 클래스에만 의존하여 Kid 클래스의 수정이 일어나지않도록 의존성을 역전시키는 원칙이다.

https://velog.io/@harinnnnn/OOP-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-5%EB%8C%80-%EC%9B%90%EC%B9%99SOLID-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%97%AD%EC%A0%84-%EC%9B%90%EC%B9%99-DIP

profile
프론트엔드개발

0개의 댓글