코드 마이그레이션(읽기: 레거시 코드)은 재미가 없습니다. 그것은 라인을 가로 질러 그것을 얻기 위해 계획과 노력의 엄청난 금액이 필요합니다. 개발자에게 가장 흥미롭거나 동기부여가 되는 작품은 아니지만 레거시 코드를 새 라이브러리 버전으로 마이그레이션하는 데 대한 결정과 올바른 환경이 필요합니다. Joda-Time to java.time은 세심한 계획과 실행이 필요한 마이그레이션 중 하나입니다.
Java 프로젝트가 Java SE 8 이전에 생동감이 뛰어나고 날짜/시간 처리를 사용하는 경우, SE 8 이전에 날짜 및 시간 기능을 처리하기 위한 우수한 라이브러리와 사실상표준인 Joda-Time을 사용했을 것입니다. 프로젝트가 여전히 Joda-Time을 사용하지만 java.time으로 마이그레이션하려는 경우 계속 읽으십시오.
Java SE 8의 릴리스에는 java.time(JSR-310)이라고 하는 새롭고 향상된 표준 날짜 및 시간 API가 포함되어 있습니다. 이제 Joda-Time 프로젝트는 Java.time(JSR-310)으로 마이그레이션하는 것이 좋습니다.
java.time(JSR-310)은 조다 타임에서 크게 영감을 받았지만, 거꾸로 호환되지 않으며 개념과 용어가 변경되었습니다. 그렇기 때문에 Joda-Time에서 java.time로 마이그레이션하려면 변경되는 모든 코드 줄에 주의해야 합니다. 이것은 시간이 많이 소요될 수 있으며 마이그레이션하기가 쉽고 자동화된 방법이 있었으면 좋겠다는 것을 거의 알 수 있습니다.
마이그레이션하는 더 좋은 방법이 있으며 이를 사용하여 마이그레이션했습니다. Sensei - 자동으로 당신에 의해 정의 조리법 (규칙)에 따라 코드 변환을 수행하는 IntelliJ 플러그인. 반복적인 마이그레이션 작업을 수행하는 대신 재사용 가능한 레시피를 정의하는 데 시간을 할애합니다. 자동화는 레거시 Joda-Time 코드를 변환할 뿐만 아니라 팀이 새 코드를 작성할 때 IDE에서 바로 지침을 따르는 데 도움이 됩니다.
당신이 머리를 시작할 수 있도록, 우리는 공개를 만들었습니다 Sensei 자바 시간 (JSR-310)에 요리 책 표준화는 덜 고통스러운 방법으로 조다 시간에서 자바 시간으로 마이그레이션하는 조리법을 포함한다. 이것은 우리가 더 많은 조리법과 더 많은 범위를 추가하기 위해 확장을 계속 하는 조리법의 성장 세트입니다.
다음은 샘플 마이그레이션의 예입니다. Sensei 레거시 코드를 마이그레이션하는 것이 고통스없이 만듭니다.
반복적인 수동 마이그레이션에서 자동화된 코드 변환까지 Joda-Time에서 java.time으로 단일 코드 줄을 마이그레이션할 때 몇 가지 숨겨진 트랩을 보여 주는 새 DateTime을 만드는 예를 살펴보겠습니다. 그런 다음 우리는 우리의 중 하나를 볼 것입니다 Sensei java.time(JSR-310) 요리책에 대한 표준화의 레시피와 이 모든 정보를 캡처하는 방법을 보여 주므로 모든 개발자가 동일한 마이그레이션을 반복해서 사용할 수 있습니다.
이 예제에서는 DateTime 필드의 값을 나타내는 7개의 int 인수에서 Joda-Time DateTime을 생성하고 있습니다.
어떻게 이것을 java.time 에 상응하는 것으로 마이그레이션합니까?
이 생성자의 조다 타임의 자바독 은 다음과 같은 말합니다.
기본 표준 시간대의 ISOChronology를 사용하여 날짜 시간 필드 값에서 인스턴스를 생성합니다. 처음에는 java.time에 DateTime 클래스가 있다고 가정할 수 있지만 그렇지 않습니다. 당신이 구글 경우 '자바 시간으로 조다 시간에서 마이그레이션' 당신은 가장 가능성이 스티븐 콜본의 블로그 게시물 조다 시간에서 자바.time로 변환 찾을 수 있습니다 .
이것은 당신에게 좋은 시작을 제공하고, 자바.time.zonedDate시간 또는 java.time.OffsetDateTime을 사용하는 방향으로 우리를 가리킵니다. 다음은 어떤 질문을 사용합니까? 아마 존다데이트는 스티븐의 의견에 근거를 둔다.
ZonedDateTime 자바도크 를 살펴보면 생성자가 전혀 표시되지 않습니다. 스티븐의 블로그 게시물로 돌아가서 우리는 더 아래로 읽었습니다.
건설 . Joda-Time에는 개체를 수락하고 형식 변환을 수행하는 생성자가 있습니다. java.time에는 공장 메서드만 있으므로 문자열에 대해 구문 분석() 메서드가 제공되지만 변환은 사용자 문제입니다.따라서 정적 공장 메서드가 있어야 하며, 정적 메서드를 검색하여 매우 가깝게 보이지만 정확히 동일하지는 않습니다.
그것은 우리의 원래 Joda-TimeTime 생성기 와 같은 7 int 매개 변수를 가지고 있지만 주의를 기울이지 않으면 중요한 세부 사항을 놓칠 수 있습니다. 7번째 매개 변수는 더 이상 밀리초를 나타내지 않으며, 대신 나노초를 기대하고 있으며, 이는 java.time이 Joda-Time에 비해 정밀도를 높이고 나노 초로 즉시 측정되기 때문입니다. 쉽게 놓칠 수 있는 중요한 세부 사항입니다. 또한 이 방법은 ZoneId를 기대하므로 이전에 필요하지 않은 이유와 왜 지금 필요한지 궁금합니다.
기본 표준 시간대를 사용할 것이라고 언급 한 원래 생성자의 자바도크를 기억하면 기본 ZoneId를 얻을 수있는 방법이 있습니까?
ZoneId용 자바도크 는 나열된 생성자에 대해 알려주지 않지만 시스템기본값() 을 사용할 수 있는 정적 메서드를 살펴보는 것입니다.
이제 ZoneId를 정리한 지금, 우리는 나노초 변환에 대한 우리의 밀리초에 대해 무엇을해야합니까? 어쩌면 우리는 변환을 수행하기 위해 java.util.cocurrent.TimeUnit을 사용할 수 있습니다.
이 메서드는 긴 반환, 그리고 우리의 방법은 int를 기대, 그래서 지금 우리 뿐만 아니라 해결 하는 변환 문제가 있다. 어쩌면 우리는 간단한 무언가를 시도 할 수 있습니다. 곱셈?
이것은 작동하지만 장소에서 조금 보이지 않습니다. 아직 눈치채지 못했다면 한 줄의 코드를 마이그레이션하는 데 상당한 시간과 노력을 기울였습니다. 그러나 당신이 상상할 수 있듯이, 우리는 손으로 할 수있는 많은 편집을 가지고 있으며, 그것은 더 나아지지 않습니다.
그러나 java.time API에서 좀 더 어려워 보이는 경우 좀 더 유창해 보이는 솔루션을 찾을 수 있습니다.
ZonedDateTime밀리초를 설정할 명백한 방법은 없지만 ChronoField.MILLI_OF_SECOND 임시 필드로 사용하여 (TemporalField 필드, 긴 새 값) 방법을 사용하여 수행 할 수 있습니다.
그리고 자바 문서는 우리를 위해 나노 초로 변환을 수행 할 것이라고 언급 :
값을 설정하는 데 이 필드를 사용하는 경우 값을 곱한 값과 NANO_OF_SECOND 설정하는 것과 동일한 방식으로 수행해야 합니다. 따라서 공장 메서드에서 나노초에 대해 0을 지정한 다음 사용하여 모든 원본 값과 밀리초가 있는 ZonedDateTime을 만들 수 있습니다.
최종 결과를 살펴보면 한 줄의 코드만 변경한 것 같습니다.
더 빠르고 쉽게 마이그레이션할 수 있는 레시피 만들기 Sensei 이 하드 원 정보를 다른 개발자와 공유할 수 있는 방법을 제공합니다. 이러한 모든 요구 사항을 캡처하는 레시피를 만들면 Sensei 마우스 클릭으로 이 마이그레이션을 수행할 수 있습니다.
A Sensei 레시피는 3가지 주요 섹션으로 구성됩니다.
우리가 살펴 보자 Sensei 이 호출을 java.time에 상응하는 것으로 마이그레이션하는 데 도움이 되는 레시피(YAML 레시피로도 볼 수 있음).
DateTime foo = 새로운 날짜 시간 (년, 월, dayOfMonth, dayOfMonth, hourOfDay, minuteOfHour, 두 번째OfMinute, 밀리오브초); 메타데이터 섹션 메타데이터 섹션에는 레시피및 사용 방법에 대한 정보가 포함되어 있습니다.
검색 섹션 의 검색 섹션은 Sensei 레시피는 이 레시피에 적용할 코드 요소를 지정합니다.
검색: 인스턴스 만들기: 아르그: 1: 유형: int 2: 유형: int 3: 유형: int 4: 유형: int 5: 유형: int 6: 유형: int 7: 유형: int 아르그카운트: 7 유형: org.joda.time.DateTime
이 검색 섹션에서는 다음과 같은 것을 볼 수 있습니다.
인스턴스 만들기 검색, 즉 생성자의 사용. 참고: 사용 가능한 검색 대상이 많이 있습니다. 생성자는 7개의 인수를 가져야 하며, 이는 argCount 속성에 의해 지정됩니다. args 1-7 은 유형 int이어야한다우리는 유형 org.joda.timeTime의 생성자 찾기
사용 가능한 수정 섹션 사용 가능한 Fixes 섹션에서일치 코드 요소에 적용할 수 있는 하나 이상의 수정 프로그램을 지정할 수 있습니다. 각 수정 에는 여러 작업이 있을 수 있으며, 경우에 따라 2개의 작업을 수행하는 단일 수정 프로그램이 있습니다.
수정 의 이름은 'Quickfixes' 메뉴에서 사용자에게 표시되며 사용자가 이 퀵픽스를 적용하면 어떤 일이 일어날지 설명합니다. 작업 목록에는 이 퀵픽스에서 수행할 작업이 표시됩니다. 다시 작성 작업은 콧수염 템플릿을 사용하여 코드 요소를 다시 작성합니다. 변수 및 문자열 교체 기능을 사용할 수 있습니다.수정할당변수 작업은 이 생성자가 변수에 값을 할당하는 데 사용되고 있는지 확인합니다. 이 경우 이 작업은 형식 별로 지정된 유형으로 선언할 변수를 수정합니다.
레시피를 사용하여 코드 변환을 수행합니다. 레시피를 작성하고 활성화하면 코드를 스캔하고 적용할 수 있는 세그먼트를 강조 합니다.
아래 스크린샷에서 대상 생성자가 표시된 것을 볼 수 있습니다. Sensei. 표시된 생성자 위로 마우스를 가져가면 레시피 단축설명설명과 빠른 픽스 옵션이 java.time.zonedDateTime으로 마이그레이션됩니다.
java.time.ZonedDate 퀵픽스로 마이그레이션 을 선택하면 레시피에 지정한 작업에 따라 코드가 변환됩니다.
팀 간 일회성 마이그레이션 및 균일한 코딩 관행- Sensei 위의 예제에서 볼 수 있으며, 한 줄의 코드 마이그레이션에는 하드 원 지식이 포함될 수 있습니다. Sensei 이러한 지식을 팀 내에서 공유할 수 있는 실행 가능한 레시피 또는 쿡북으로 전환할 수 있습니다. 일회성 마이그레이션 스프린트를 계획하거나 Joda-Time 코드를 우연히 볼 때 java.time에 대한 점진적인 즉각적인 변환을 수행하는 방법을 취할 수 있습니다. 논리 적 단계 또는 단계에서 마이그레이션을 수행하고 스캔 한 파일의 범위를 확장하거나 줄이는 방법으로 레시피를 활성화 / 비활성화 할 수 있습니다. Sensei - 코드 마이그레이션을 덜 고통스럽게 만드는 유연성.
라이브러리 마이그레이션은 Sensei 을 사용하여 프로젝트를 표준화할 수 있는 다양한 방법 중 하나에 불과합니다. 풀 리퀘스트에서 또는 직접 코딩할 때 자주 접하게 되는 안티 패턴이나 특정 수동 코드 변환을 항상 경계할 수 있습니다. 개발자가 자주 놓치는 코딩 가이드라인이 있다면 가이드라인을 레시피로 변환하여 개발자가 승인된 코드 변환을 안심하고 적용할 수 있도록 할 수 있습니다.
질문이 있으시면, 저희는 여러분으로부터 듣고 싶습니다! 슬랙에 우리와 함께 : sensei-scw.slack.com