유지보수를 하다가 보면, 기존에 잘 쓰고(?) 있는 API를 버리고 새로운 API를 만들때가 있다.

이런 경우는 다양하게 일어날수가 있는데, 대표적인 경우는 하위버젼 호환성이 없는 프레임워크떄문에 문제가 생길수 있고, 프레임워크가 바뀌어서 발생하는 경우도 있다.

편의상 후자라고 가정을 하자. 프레임워크의 변경으로 인해서 새로운 스타일로 기반 클래스나 common 성격의 API를 구현 할때가 있다.

레거시 코드의 API가 맘에 들지 않아서 같은 기능 또는 거의 비슷한 기능의 클래스를 만들어서 더 잘 구현을 했다. 구현 자체는 전보다 많이 훌륭해졌지만, 새로 만드는 기능에만 적용이 되고 과거에 있던 레거시들은 신규API로 변경하지 못했다.

과거와 현재의 클래스가 패키지만 틀리고 이름만 조금 틀리고, 구현은 거의 같은 2-3개정도 되는 경우도 흔히 볼수 있다. 무엇이 문제일까? 유사 클래스가 3개정도 존재를 할때 새로운 feature를 추가하려면 결국 3개의 클래스에 다 변경을 가해야 한다. 좀더 나은 코드상태를 유지 하기 위해서 했던 노력들인데 결국 더 큰 유지보수의 부담으로 가져오는 것이다. 그렇다. 중복...중복이 발생해서 변경도 어렵고 변경을 할때 주의를 기울이지 못해서 버그가 자주 발생한다.

그럼 어떻게 변경을 가하는 것이 좋을까?

첫째, 신규 API를 만들었으면 모든 코드에 그 클래스를 이용하도록 빠른 시간 안에 수정을 한다.
이 경우는 코드의 양이 적었을  때와 in place에 모든 코드를 볼수 있을때 가능하다. 대형 시스템에서는 거의 사용이 불가능한 방법이다.

둘째, 신규API를 만들고, 레거시 코드(기존에 코드)들을 신규API를 바라보게 만들어서 위임(delegate)을 한다. 그리고 레거시 코드 클래스에 에 deprecated를 박아준다. 변경이 생겼을 때는 2가지 스타일로 처리를 하면 된다.
1. 신규 클래스와 레거시 클래스는 같은 인터페이스를 가지고 있을 것이고, 구현은 신규 클래스에만 있을 것이기때문에 변경을 할때 신규 클래스만 수정하면 레거시 클래스는 고칠 필요가 없어진다.
2. 새롭게 인터페이스를 추가할 경우는 2군데 모두 추가를 하고, 신규API에 구현을 한 다음, 레거시 클래스에는 신규 클래스를 dependency를 가지고 위임을 시키는 것이다.

User inserted image
<레거시 클래스>
/**
 * @deprecated {@link NewBlogCookie}
 */
public class LegacyBlogCookie {

   private NewBlogCookie newBlogCookie ;

   public LegacyBlogCookie (NewBlogCookie newBlogCookie ){
       this.newBlogCookie = newBlogCookie ;
   }
   public void createCookie(){
        newBlogCookie.createCookie();
   }
}

<신규 클래스>
public class NewBlogCookie {
     public void createCookie(){
        // 좋은 표현의 좋은 API를 맘껏 구현해라~!
     }
}


대부분의 유지보수 중의 수정은 1번의 경우일 것이다. 2번의 경우도 발생을 하지만, 중복된 코드를 2번 수정하는 것보다 훨씬 좋다. 주의할 사항은 상호참조가 되지 않고 레거시 클래스가 신규 클래스를 가지는 단방향 참조로 해야 한다.

시간을 두고 레거시 코드에서 기존 클래스의 dependency를 신규 클래스로 점진적으로 변경을 하다가 모든 기능에서 사용하지 않을 경우 삭제를 하면 된다.

 
운영 및 유지보수라는 단어의 의미는 너무나 다양하고, 광범위하게 쓰인다

소프트웨어 유지보수의 중요성 을 보면서 다시 한번 유지보수에 대해서 생각을 하게 되었고, 테스트의 중요성에 대해서 생각을 해봤다.

시스템에 따라서 행위가 많이 달라지기 때문이다. 개발자들은 유지보수를 많이 해봐야한다. 유지보수를 해보지 않고, 신규 개발을 잘하기는 정말 어렵다. 시스템의 라이프싸이클이 개발하는 기간보다는 유지보수를 하는 기간이 훨씬 길다는 사실은 너무나 잘 아는 이야기이다.

나는 하나의 시스템을 가지고,  4년동안 유지보수를 해본 경험이 있다. 앞으로도 쉽게 가질 수 있는 소중한 경험이었다. 그 경험은 나에게 큰 도움이 되고 있다. 유지보수를 오래할 수록 안정적이게 된다. 물론, 그 도메인 영역에 대한 이해도가 높아져서이기도 하지만, 자주 있는 일에 대한 테스트를 하나씩 만들어서 추가를 하기때문이기도 하다.

제일 중요한 포인트는 어떤 방식으로던지 테스트가 가능해야 하다는 것이다. 테스트를 1초라도 빨리할 수 있으면 유지보수시에 잦은 변경사항을 적은 노력으로 버그를 최소화하면서 변경을 할수가 있다. 초보시절에는(junit을 사용하기전에는) 주로  웹서버에서
굵게주로 테스트를 하는 mock페이지를 많이 만들었는데, 몇 년전부터 지금까지는 junit을 이용해서 단위 테스트를 가능한 많이 만들고 있다.

단위 테스트만큼 빠르게 테스트가 가능한 것은 없을 것이다.
난 더욱더 테스트 중독에 빠지려고 한다.





유지보수에 대한 이야기가 okjsp에 올라와있습니다.

프로그래머의 피할수 없는 운명
http://www.okjsp.pe.kr/seq/95644

개발자가 업무를 진행을 하다가 보면, 신규개발보다는 유지보수를 하는 시간이 더 깁니다. 소프트웨어가 개발하는 시간보다 그 코드가 유지되는 시간이 일반적으로 더 길다는 이야기입니다.

개발자가 업무를 진행을 할때 신규개발 업무보다는 기존에 있는 코드를 유지보수하는 일이 더 많다는 이야기입니다. 그것이 피할수 없는 운명이라면, 잘 이겨낼 수 있는 전략이나 테크닉이 필요합니다.

트렌드와 신기술때문에 유지보수가 어려운 코드를 만든다는 것은 하나의 변명입니다. 그것들을 익히기 위한 시간이 낭비가 될수도 있지만, 기본적으로 많은 이들이 불편하지 않아야 하는 것을 중요하게 생각을 해야 합니다. 예를 들면, 일반적으로 중복코드가 적을 수록 유지보수가 쉽다고 만인이 생각을 한다면, OOP가 아니라 그 할아버지의 개념을 생각해서 만들어야 할 것입니다.

물론, 남이 개발한 코드를 보고, 빠르게 쉽게 이해하기는 어려운 일입니다. 명확하게 직관적으로 코드를 만든 다는 것은 너무나 어려운 일입니다. 적은 메타포보다는 잘 만들어진 메타포가 더 심플하고 가독성이 띄어날 때가 많습니다. 너무 형식에 얽매이지 말았으면 합니다.

기존에 통용되는 단어, 잘못 짜여진 코드 무조건 버리려고만 하지 말고 포용할 수 있는  마음을 키워야 겠습니다. 유지보수를 잘할수 있는 기본은 레거시를 포용할 수 있는 마음입니다. 기술은 마음 다음에 중요한 것이 아닐까 생각합니다.




BLOG main image
OOP and Java by ologist

공지사항

카테고리

All (649)
private!! (106)
WEB & IT (140)
Developer (400)