이런 경우는 다양하게 일어날수가 있는데, 대표적인 경우는 하위버젼 호환성이 없는 프레임워크떄문에 문제가 생길수 있고, 프레임워크가 바뀌어서 발생하는 경우도 있다.
편의상 후자라고 가정을 하자. 프레임워크의 변경으로 인해서 새로운 스타일로 기반 클래스나 common 성격의 API를 구현 할때가 있다.
레거시 코드의 API가 맘에 들지 않아서 같은 기능 또는 거의 비슷한 기능의 클래스를 만들어서 더 잘 구현을 했다. 구현 자체는 전보다 많이 훌륭해졌지만, 새로 만드는 기능에만 적용이 되고 과거에 있던 레거시들은 신규API로 변경하지 못했다.
과거와 현재의 클래스가 패키지만 틀리고 이름만 조금 틀리고, 구현은 거의 같은 2-3개정도 되는 경우도 흔히 볼수 있다. 무엇이 문제일까? 유사 클래스가 3개정도 존재를 할때 새로운 feature를 추가하려면 결국 3개의 클래스에 다 변경을 가해야 한다. 좀더 나은 코드상태를 유지 하기 위해서 했던 노력들인데 결국 더 큰 유지보수의 부담으로 가져오는 것이다. 그렇다. 중복...중복이 발생해서 변경도 어렵고 변경을 할때 주의를 기울이지 못해서 버그가 자주 발생한다.
그럼 어떻게 변경을 가하는 것이 좋을까?
첫째, 신규 API를 만들었으면 모든 코드에 그 클래스를 이용하도록 빠른 시간 안에 수정을 한다.
이 경우는 코드의 양이 적었을 때와 in place에 모든 코드를 볼수 있을때 가능하다. 대형 시스템에서는 거의 사용이 불가능한 방법이다.
둘째, 신규API를 만들고, 레거시 코드(기존에 코드)들을 신규API를 바라보게 만들어서 위임(delegate)을 한다. 그리고 레거시 코드 클래스에 에 deprecated를 박아준다. 변경이 생겼을 때는 2가지 스타일로 처리를 하면 된다.
1. 신규 클래스와 레거시 클래스는 같은 인터페이스를 가지고 있을 것이고, 구현은 신규 클래스에만 있을 것이기때문에 변경을 할때 신규 클래스만 수정하면 레거시 클래스는 고칠 필요가 없어진다.
2. 새롭게 인터페이스를 추가할 경우는 2군데 모두 추가를 하고, 신규API에 구현을 한 다음, 레거시 클래스에는 신규 클래스를 dependency를 가지고 위임을 시키는 것이다.

/**
* @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를 신규 클래스로 점진적으로 변경을 하다가 모든 기능에서 사용하지 않을 경우 삭제를 하면 된다.
