2009-02-09 6 views
6

저는 레거시 Java 시스템을 유지 보수하고 리팩토링해야합니다. 저는 현재 Java에 익숙하지만 C# 및 .NET을 사용합니다.레거시 Java 시스템 학습

레거시 시스템은 클라이언트/서버 아키텍처 인 RMI를 사용하며 1.4 JVM 용으로 설계되었습니다. 그것은 UI (내가 말할 수있는 한), Swing 및 AWT에 사용됩니다.

내 질문은 : 내가 방금 건네 준 코드베이스에 관해서 가장 좋은 방법은 무엇입니까? 스크린의 플로우 차트를 생각하고, RMI 호출 사이의 경계를 정의하고, 단위 테스트를 작성합니다 (테스트 할 수있는 비트의 경우).

익숙하지 않은 코드베이스를 건네고있는 상황에서 무엇을합니까?

감사합니다.

-Jarrod

답변

5

내가 손으로 해요 새로운 코드로 할 첫 번째 것은 기존 단위 테스트에서 볼 수 있습니다. 일반적으로 새로운 테스트를 작성하는 것이 두 번째 일입니다.

+0

그게 의도 된 것인지 잘 모르겠지만 다음 일은 대개 새로운 테스트를 작성하는 것이 재미 있다는 것을 알 수 있습니다. (기존의 단위 테스트에 대해 많이 언급하지 않습니까? :) – Learning

+0

제 동료들을 경멸하는 것이 아닙니다. , 그러나 나는 아직 단위 테스트 (심지어 내 자신을 향상시킬 수있는)의 100 % 완전한 세트를 보지 못했습니다. :) 또한 필자는 필기 시험이 필자에게 필독서를 읽는 것보다 배우기에 더 좋은 방법임을 알게되었다. –

+0

ROTFL, good one :))))))))))) – IAdapter

0

RMI가있는 Java 1.4는 기존의 것이 아니며, 일부 표준에서는 거의 새로운 기능입니다! 당신이 일이있는 곳을 숙지하기 위해 할 수있는 어떤

금지 - 단위 테스트 몇 가지 UML 다이어그램을 작업 코드/전화 추적 등

그것의 작은 부분에서 시작하여 추적을 시도 코드 경로 상황을 잘 파악하고 코드를 살펴 봐야하는 작은 수정/개선 사항을 스스로에게 할당하십시오.

+0

Java 1.4는 Java 표준 (릴리스 이후 7 년)으로 꽤 오래되었습니다. Sun은 수명 종료 시점에서 2 년이 지난 후 10 월에 1.4 시간 동안 "서비스 수명 종료"(EOSL)를 선언했습니다. Java 5는 올해 말에 EOSL에 도달합니다 (http://java.sun.com/products/archive/eol.policy.html). –

+0

어떤 경우에도 레거시라는 용어는 단순히 회사가 더 이상 시스템을 사용하지 않거나 더 이상 원래 개발자를 고용하지 않았 음을 의미하므로 Java 1.4에 대한 커뮤니티의 느낌에 관계없이 코드는 "오래되었습니다". – Karl

+0

"실제적으로 새로운" 는 대부분 혀가 뺨에 들었지만 EOL에 근접한 자바 5가 1.4가 여전히 일반적이지 않다는 것을 의미하지는 않습니다. 어쨌든, 칼은 "유산"이라는 용어의 진정한 의미에 맞습니다. –

4

코드베이스의 품질에 따라 크게 달라집니다. 사실, 코드를 더 명확하게 정의 할 수 있습니다. 이는 코드가 얼마나 명확한 지, 얼마나 잘 설명되어 있는지에 달려 있습니다. (필자는이 코드를 잘 설명하지 않은 레거시 코드베이스를 상속하는 위치에 반복적으로 있었던 사람으로이 코드를 작성합니다.)

코드베이스가 나쁠수록 외부에서 기능을 추론 할 필요가 있습니다. 기능이 무엇인지 알 수 없다면, 적어도 코드베이스가 무엇인지 알아낼 수 있습니다. GUI는 그것이하고 있음을 암시하는 것처럼 보입니다. RMI 인터페이스를 사용하면 GUI가보기에 필요한 단순화 된 그림을 얻을 수 있다는 점에서 축복이 될 수 있습니다. 원격 인터페이스에서 추상화하는 것이 좋습니다.

코드베이스가 정말 좋지 않은 경우 단위 테스트가 도움이되지 않을 수 있습니다. 올바르게 구현 되더라도 잘못된 코드를 테스트 할 수 있습니다. 내가 상속 마지막의 예는 : (이름과 설명이 의도적으로 제거 - 그들이 어떤 경우에는 원래에 도움이되지 있었다) 그것을 알고 보니

public static int[] a (List<int[]> input){ 

    ... lots of opaque rubbish 
    return b(input); 
} 

public static List<int[]> b{ List<int[]> input) 
{ 
    ... more crap.... 
    return some horribly mangled list of int[]; 
} 

, 성취 무엇을 정렬했다 배열은 두 번째 요소의 값으로 배열됩니다. 이 경우 정확하게 b을 테스트하면 올바르게 작동하지 않습니다. 사용 분명히 아니다

  • 제거 코드 :

    제안은 당신이 당신의 정신을 유지할 수 있도록 도와줍니다.

  • "마법의 숫자"
  • 을 찾아내어 하드 코드 파일, 경로 또는 리소스 참조를 찾아서 속성이나 다른 중심적인 일반적인 방법으로 처리하십시오.
  • 앱이 실제와 같은 방식으로 작동하는지 여부를 확인하십시오. 사용자가 "실제로 제대로 작동하지 않는다고 느꼈던 것을 실제로 나타낼 수는 없거나 머리를 꼬리로 만들 수없는 몇 가지 복잡한 기능에는 이상하지 않습니다. ".
  • 최초 설계 당시의 원본 설명서 또는 사양을 찾으십시오.
  • 1.4에 대해 언급 했으므로지도를 제네릭 화하면 어떤 종류의 개체가 전달되는지 분명히 알 수 있습니다. 객체가 HashMap에 의해 뒷받침되고 객체가 어떻게 채워지는지 미스테리라면 실제로 문자열을 정수로 매핑한다는 사실을 결정하기 위해 자신의 삶을 단순화 할 수 있습니다. 실제로 생각한 것보다 더 쉽게 파악할 수 있습니다 하고있다.

물론 코드베이스가 잘 작성되어 있으면 대부분의 경우 필요하지 않지만 어떤 경우에는 작업이 훨씬 쉬울 것입니다. 그리고 행운을 빌어.

1

새로운 코드를 수신 할 때 가장 먼저해야 할 일은 "작동 시키십시오"입니다. 이것에 의하여 말 :

  • 처음

  • (있는 경우 메모를 설치에 따라) 다음

  • 설치 (일부 중요한 유스 케이스를 사용자 설명서를 읽고 실행하여) 그것으로 자신을했습니다

  • 그런 다음 주요 리버스 엔지니어링을 통해 주요 레이어를 찾습니다. (나중에 회귀 테스트에 유용 할 것이다 첫번째 수용 수준)

  • 그때 나는 새로운 테스트 케이스를 작성에 대해 생각할 수있는 클래스와 의존성

  • 는 나는이 기능을 추가하는 방법에 대한 몇 가지 "도전"나 자신을 줄 (필요하지 않더라도) 기존 기능의 성능을 향상시키는 것 : 기존 코드베이스를 파고들 수있는 좋은 방법입니다.

  • 물론, 알려진 버그/RFE가있는 경우 작업하겠습니다. 이 첫 번째

특정 경우에 RMI 호출, 호출 할 호출 또는 호출 순서를 문서화하고 가능한 경우 사용 수준 기능과 연결하려고 시도합니다.

이 시스템의 주된 목적은 무엇보다 중요한 사실입니다 (고객이이 시스템을 사용하는 이유는 무엇입니까?). 목표를 알고이를 명심한다면 코드를 유지하면서 이러한 목표에서 벗어날 수 있습니다.

0

빌드하고 실행하면 첫 번째 문제가됩니다. 해결하고자하는 문제에 대한 이해를 시작하십시오.

아마도 JUDE와 같은 UML 도구로 가져 와서 클래스가 상호 작용하는 방식을 알 수 있습니다.

JUnit 테스트를 작성하는 것이 좋습니다. 앱이 계층화 된 모습을보고 싶습니다. 테스트하기가 힘들다면 아마 너무 어울릴 것입니다. 단위 테스트를 통해 알 수 있습니다. 또한 리팩토링이 필요한 경우 안전망을 제공합니다.

JDK 1.4? 지원 생활이 끝난 지요. 또한 JDK 5, JDK 6에서 코드가 빌드되고 실행되는지 확인하고 싶습니다. JMeter에 대한 JUnit 테스트 중 일부를 수행하고 5 명의 동시 사용자를 대상으로 신속한 테스트를 수행 할 수 있습니다.

데이터 모델이있는 경우이를 ERWin으로 가져 와서 테이블, 개체 및 스크린이 함께 흐르는 방식을 살펴보십시오.

2

저에게 새로운 코드로 작업하는 데 도움이되는 한 가지 - 잘 작성된 코드에 대해 필요성이 훨씬 적습니다. 하루나 이틀 동안 엄청 리팩터링 한 다음 모든 변경 사항을 삭제하는 것입니다. 이 프로세스는 코드가하는 일을 이해하는 데 도움이됩니다. 코드로 작업하면 이해하는 데 도움이됩니다. 또한 코드의 어떤 부분이 허약하다는 것을 가르쳐줍니다.

새로운 버전의 Java로 마이그레이션 할 기회가있는 경우 모든 컬렉션을 일반화하면 전달되는 데이터 유형을 이해하는 데 도움이됩니다.

물론 테스트 랩에 소프트웨어를 설치하고 소프트웨어가 무엇을하는지 이해하기 위해 소프트웨어를 설치 한 후에이 작업을 수행합니다.

편집 : 내 대답을 생각하면 모든 진단 추적 및 로깅을 사용 가능하게 설정하고 시스템을 사용하고 로그를 조사하는 것이 유용합니다. 통신 프로토콜 추적이 있으면이 추적을 보면 같은 테스트의 Wireshark 추적과 함께 코드에서 사용 된 통신 프로토콜을 이해하는 데 도움이됩니다.

또 다른 유용한 마이그레이션은 이전 동시성 라이브러리에서 새로운 Java 5 (및 6) 동시성 라이브러리로 마이그레이션하는 것입니다. 이것은 쓰레드가 어디에 있는지, 언제 쓰레드가 시작되고 언제 종료되는지 이해하는 데 도움이 될 것입니다.

물론 익숙하지 않은 코드 기반에서 코드를 변경하면 아무 것도 손상되지 않았는지 확인하기 위해 적절한 테스트가 수행된다고 가정합니다! 그러나이 균형을 맞추기 위해 심하게 작성된 코드를 리팩토링 한 후 새로 도입 된 버그는 리팩터링 이전의 버그보다 훨씬 쉽게 발견된다는 것을 알게되었습니다.

0

물론 단계별로 시도 할 수 있습니다. 느리지 만 코드를 통해 하루를 보냈다가 나중에 버그를 검색하는 일을 절약 할 수 있습니다 ...

또한 청소기 사냥 방식을 시도하고 모든 기능 목록을 작성한 후 코드를 검색합니다.

0

먼저 구조를 이해하기 위해 코드를 살펴보십시오. 그런 다음 디버그 모드로 앱을 실행하고 두 번 실행하십시오. 이것은 당신에게 흐름과 구조를 보여줄 것입니다.

Netbeans를 사용하여 클래스 다이어그램을 리버스 엔지니어링하십시오.

1

마이크 힐 (Mike Hill)이 참석 한 가운데 강연 코드를 다루는 데 사용하는 프로세스에 대해 이야기했습니다. 그는 "마이크로 테스트 (microtesting)"라고 부르며, 테스트 할 각 것을 (자체 기능 또는 작은 객체로) 분리하고 테스트를 작성합니다. 이 테스트는 비즈니스 감각으로 사물을 주장하는 것을 의미하지는 않습니다. 테스트되는 라인이 실행 된 후에 시스템이 남아있는 상태를 파악하기위한 것입니다. 일반적으로 그는 변수에 디버거에있는 값이 있다고 주장합니다. 당연히 이러한 테스트는 처음에는 통과 할 것이지만 충분히 작성한 후에는 시스템의 스냅 샷을 효과적으로 얻을 수 있습니다.

테스트가 완료되면 코드의 리팩토링을 시작하여 수행하려고 시도했던 것을 이해하려고 할 수 있습니다. 그는 "microtests"가 함수 (또는 객체)의 동작 방식을 약간 변경 한 경우 실패 할 수 있기 때문에 안전하게 수행 할 수 있습니다.그것이 설계 변경을 크게 할 수는 없지만 많은 소음을 없애고 시스템이 수행하는 작업에 대한 그림을 얻을 수있었습니다. 코드가 달성 한 내용에 대해 명확한 아이디어를 얻은 후에는 버그를 발견하고 개선하기 시작할 수 있습니다.

여기에는 많은 자유 리소스가 없으므로 링크를 제공하지 않습니다. 다행히도 나는 당신에게 아이디어를 줄 수있을 정도로 충분히 설명 할 수 있었으면 좋겠다.

1

경험에 의하면 레거시 시스템을 배울 때 3 가지 주요 목표가 있음을 경험했습니다.

  • 코드가
  • 이 그들을
  • (결정적으로) 알아보기 않는 방법에 대해 알아보십시오 어떻게해야 어떤 배우가 그들에게 길을 않는 이유는 그 부분의 세 가지 매우이다

않습니다 중요하며 시작하는 데 도움이되는 몇 가지 트릭이 있습니다.

먼저 코드를 마우스 오른쪽 버튼으로 클릭 (또는 IDE에서 사용)하여 모든 것을 이해하도록 유도하십시오. 당신은 아마 당신의 마음 속에 모든면을이 방식으로 유지할 수 없을 것입니다. 특히 각 라인이 당신이 무엇인지 이해하기 위해 다른 여러 클래스들을 보도록 강요 할 때 그렇습니다.

가능하면 문서를 읽으십시오. 일반적으로 다음과 같은 모든 것을 구축하기위한 정신적 프레임 워크를 빨리 얻을 수 있습니다.

가능한 경우 테스트 사례를 실행하십시오.

질문이 있으시면 아는 사람에게 물어 두려워하지 마십시오. 허락하신다면, 익숙하지 않은 쿼리로 다른 직원의 시간을 낭비해서는 안되지만, 단순히 이해할 수없는 것이 있다면 (이것은 특히 다음과 같이 개념을 구현하는 것이 더 바람직하지 않겠습니까? ___ "또는 무언가), 뭔가를 엉망으로 만들고 왜 그 이유를 모르기 전에 대답을 찾아내는 것이 좋습니다.

마침내 코드를 읽으면 논리적 인 "메인"장소에서 시작하여 거기에서부터 시작하십시오. 코드를 위에서 아래로 또는 알파벳 순서로 읽지 마십시오. (이것은 분명합니다).