티스토리 뷰



[프로그래밍 방법론] 효율적인 외부 코드 및 오픈 소스 이용법 

(8장. 경계)  - Clean Code


이 글은 Clean Code 책의 내용을 정리한 것입니다.


시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드뭅니다. 때로는 패키지를 사고, 오픈소스를 이용하기도 합니다. 어떤 식으로든 외부 코드를 자신의 코드에 깔끔하게 통합을 해야 합니다. 이 글에서는 소프트웨어 경계를 깔끔하게 처리하는 기법과 기교를 살펴보도록 하겠습니다.


1. 외부 코드 사용하기


프레임워크 제공자는 적용성을 넓히려는 반면 사용자는 자신의 요구에 집중하는 인터페이스를 바라기 때문에 둘 사이에는 특유의 문제가 발생을 합니다.


java.util.Map을 살펴보면, Map은 다양한 인터페이스로 수많은 기능을 제공하고 있습니다. Map에 대한 다양한 함수는 아래의 링크를 통해서 확인을 할 수 있습니다. 



Map의 메소드를 살펴보면 Clear라는 함수를 볼 수 있습니다. 이는 Map 객체를 접근하는 모든 사용자는 Map의 내용을 삭제할 수 있다는 의미가 됩니다. 또한 Map에 특정 객체만 삽입을 하기위해 만들었지만, Map은 유형을 제한하지않는 특징을 가지고 있습니다. 마음만 먹으면 누구든지 새로운 객체 유형을 추가할 수 있게 되는것이죠.


만약 Sensor라는 개체 타입을 이용하는 Map을 만든다면 아래와 같은 코드를 구성할 수 있습니다. 


Map sensors = new HashMap();

Sensor s = (Sensor) sensors.get(id)


위의 코드는 사용자가 Sensor 개체로 Map에 들어있는 개체의 유형을 변환(Casting) 해줘야 합니다. 이렇게 구현을 하면 코드의 의도도 분명하지 않을 뿐더러 가독성도 떨어지는 단점을 가지고 있습니다.


이 문제를 해결하기 위해서는 제너릭(Generic)을 사용해야 합니다. 


Map<string, Sensor> sensors = new HashMap<Sensor>();

Sensor s = sensors.get(id);


위의 코드도 사용자에게 필요하지 않는 기능을 제공하지 않는다라는 문제를 해결하지 못합니다. 따라서 Get을 하기 위한 클래스를 하나 이용하는것이 사용자를 위한 최소한의 코드라고 할 수 있습니다. 


public class Sensors

{

private Map sensors = new HashMap();

public Sensor GetSensor(string id)

{

return sensors.get(id);

}

}


코드를 이렇게 제공하게 되면 경계 인터페이스인 Map이  Sensor안에 숨어버리기 때문에, Map 인터페이스가 변경이 되더라도 나머지 프로그램에는 영향을 미치지 않게 됩니다. 변하는것을 따로 떼어내라는 객체 지향의 캡슐화 개념을 적절히 사용한 예라고 볼수 있겠습니다.


2. 경계 살피고 익히기


외부 코드를 사용하면 적은시간을 들여 더 많은 기능을 제공할 수가 있습니다. 하지만 외부 패키지에 대한 테스트의 확인이 필요하게 됩니다. 코드를 개발하다 보면 자신의 코드가 문제인지, 외부 라이브러리가 문제인지 명확히 파악하기 어려워 오랫동안 디버깅을 할때도 있습니다.


이러한 문제를 해결하기 위해서 '학습 테스트'라 불리는 방법을 사용합니다. 학습테스트는 외부 코드를 이용할 때 외부 코드를 이용하지 않고, 자신의 코드를 작성해 테스트한 뒤 외부 코드를 적용하는 방법입니다. 이런식으로 테스트를 진행하면 외부 코드의 문제여부를 명확히 파악할 수 있습니다.


3. log4j 익히기


log4j란?


log4j는 자바기반 로깅 유틸리티이다. 디버그용 도구로 주로 사용되고 있다. log4j의 최근 버전에 의하면 높은 등급에서 낮은 등급으로의 6개 로그 레벨을 가지고 있다. 설정 파일에 대상별(자바에서는 패키지)로 레벨을 지정이 가능하고 그 등급 이상의 로그만 저장하는 방식이다.


log4j는 log 화면 출력, 파일 저장등 다양한 기능을 제공하고 있습니다. log4j에 대한 사용법을 명확히 인지한뒤 테스트하고 이를 캡슐화 하여 Logger 클래스를 만든다면 기존의 코드와 결합도가 떨어진 코드를 작성할 수 있습니다.


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


앞에서 말한 학습 테스트에 드는 비용이 없습니다. 프로그램을 개발하기 위해서는 API를 배워야 하므로 이는 필요지식을 확보할 수 있는 쉬운 방법입니다. 학습 테스트는 이해도를 높여주는 정확한 실험이기도 합니다. 


이는 노력에 대한 투자보다 얻는 성과가 더 큽니다. 패키지가 새로 나올때 마다 학습 테스트를 진행한다면 패키지의 새버전이 나와도 적용하기가 쉬워집니다. 그렇지 않다면 오래된 버전을 필요이상으로 오랫동안 사용할려고 하게 될겁니다. 


5. 결론: 깨끗한 경계


소프트웨어 경계에서는 많은 일이 발생합니다. 코드 변경이 대표적인 예이지요. 소프트웨어 설계가 우수하다면 변경에 많은 비용이 들지 않습니다. 통제하지 못하는 코드라면 항후 발생하는 변경비용이 지나치게 커지므로, 이를 경계해야 합니다. 


경계에 위치한 코드는 깔끔하게 분리하는 것이 좋습니다. 또한 학습 테스트도 많이 진행하는것이 좋습니다. Map에서 이야기 한것처럼 새로운 클래스로 외부 경계를 감싸거나, Adapter 패턴을 적용하여 외부 코드를 따로 떼어 놓는것도 하나의 방법이 될 수 있습니다.


이렇게 되면 코드 가독성이 높아지며, 경계에 대한 인터페이스 사용의 일관성도 좋아지고 수정시 변경할 코드도 줄어들게 될것입니다.


이 글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.



댓글