Java 코드를 Ceylon 코드로 변환 할 때 때때로 검증 및 초기화를 혼동하는 Java 클래스 생성자가 발생합니다. 간단하지만 인공적인 코드 예제를 사용하여 설명하고 싶은 것을 설명합시다.
나쁜 코드
다음 Java 클래스를 고려하십시오. (남자, 집에서 그러한 코드를 쓰지 마십시오)
공개 수업 기간 {개인 최종 날짜 시작 Date; 개인 최종 날짜 종료; // 주어진 문자열이 유효한 날짜를 나타내지 않으면 null을 반환합니다. 개인 날짜 구문 분석 (문자열 날짜) {... ...} public public public public public (문자열 시작, 문자열 끝) {startDate = parsedate (start); endDate = ParsEdate (끝); } public boolean isvalid () {return startDate! = null && endDate! = null; } 공개 날짜 getStartDate () {if (startDate == NULL) TRASH NEW IRMEGALSTATEEXCEPTION (); Return StartDate; } public Date getEndDate () {if (endDate == NULL) 던지기 새로운 불법 스테이트 exception (); 반환 종료; }}이봐, 전에 경고 했어, 그것은 인공적이다. 그러나 실제 Java 코드에서 이와 같은 것을 찾는 것은 실제로 드문 일이 아닙니다.
여기서 문제는 입력 매개 변수 (Hidden Parsedate () 메소드에서)의 검증이 실패하더라도 여전히 기간 인스턴스를 얻는다는 것입니다. 그러나 우리가 얻는 기간은 "유효한"상태가 아닙니다. 엄격하게 말하면, 무슨 뜻입니까?
글쎄, 객체가 공개 작전에 의미있게 응답 할 수 없다면, 나는 그것이 밸류 적이 아닌 상태에 있다고 말할 것입니다. 이 예에서 getStartDate () 및 getEndDate ()는 불법 스테이트 exception 예외를 던지는데, 이는 "의미가 없다고 생각하지 않는 경우입니다.
반면 에이 예제를 살펴보면 기간을 설계 할 때 여기에서 타입 안전에 실패했습니다. 확인되지 않은 예외는 유형 시스템에서 "공동성"을 나타냅니다. 따라서 더 나은 기간 유형-안전 디자인은 확인되지 않은 예외를 사용하지 않을 것입니다.
(실제로 실제 코드에서는 NULL을 확인하지 않는 getStartDate () 메소드가 발생할 가능성이 높습니다.
위의 기간 클래스를 클래스 클래스의 클래스 형식으로 쉽게 변환 할 수 있습니다.
공유 클래스 기간 (문자열 시작, 문자열 끝) {// 주어진 문자열이 유효한 날짜를 나타내지 않으면 null을 반환합니다. 구문 분석 (문자열 날짜) => ...; value MaybestArtDate = ParsEdate (시작); value maygrenddate = parsedate (end); 공유 부울 유효한 => MaybestartDate가 존재합니다 && 아마도 enddate가 존재합니다. 공유 날짜 startDate {Assert (ensists maybestartDate); MaybestartDate를 반환합니다. } 공유 날짜 endDate {assert (exists maybestArtDate); MaybestartDate를 반환합니다. } 공유 날짜 endDate {assert (exists maygendDate); return maygenddate; }}물론,이 코드는 원래 Java 코드와 동일한 문제를 겪게됩니다. 두 가지 주장 상징이 우리에게 소리 쳤다. 코드의 유형 안전에 문제가 있었다.
Java 코드를 더 좋게 만드십시오
Java 에서이 코드를 어떻게 개선합니까? 글쎄, 여기에 Java의 비판 된 점검 된 예외의 예는 해결하기에 매우 합리적입니다! 생성자로부터 확인 된 예외를 던지기 위해 기간을 약간 수정할 수 있습니다.
공개 수업 기간 {개인 최종 날짜 시작 Date; 개인 최종 날짜 종료; // 주어진 문자열이 유효한 날짜를 나타내지 않으면 던지기 개인 날짜 구문 분석 날짜 (문자열 날짜) 날짜 formatexception {...} 공개 기간 (문자열 시작, 문자열 끝)을 던지는 날짜 formatexception {startDate = parsedate (start); endDate = ParsEdate (끝); } 공개 날짜 getStartDate () {return startDate; } 공개 날짜 getEndDate () {return endDate; }}이제이 솔루션을 사용하면 비 균형이없는 상태에서는 기간을 얻지 못할 것입니다. 기간을 인스턴스화하는 코드는 컴파일러가 유효하지 않은 입력을 처리하기 위해 컴파일러에 의해 처리되며, 이는 DateFormateXception 예외를 포착합니다.
시도 {기간 p = 새 기간 (시작, 끝); ...} catch (dateformatexception dfe) {...}이것은 점검 된 예외의 멋지고 완벽하며 올바른 사용이며, 불행히도 위와 같은 점검 된 예외를 사용하여 Java 코드를 거의 볼 수 없습니다.
실론 코드를 더 잘 만드십시오
실론은 어때? 실론에는 확인 된 예외가 없으므로 다른 솔루션을 찾아야합니다. 일반적으로 Java가 함수를 호출하고 점검 된 예외를 던지는 상황에서 Ceylon은 함수를 호출하고 노조 유형을 반환합니다. 클래스의 초기화는 클래스 자체를 제외한 유형을 반환하지 않기 때문에 공장 기능을 만들기 위해 혼합 초기화/검증 로직을 추출해야합니다.
// 주어진 문자열이 유효한 날짜를 나타내지 않으면 dateformaterror를 반환합니다 | dateformaterror parsedate (문자열 날짜) => ...; 공유 기간 | dateformaterror parseperiod (문자열 시작, 문자열 끝) {value startdate = parsedate (start); if (dateformaterror startDate) {return startDate; } value enddate = parsedate (end); if (dateformaterror endDate) {return endDate; } return period (startDate, endDate);} 공유 클래스 기간 (startDate, endDate) {공유 날짜 시작 date; 공유 날짜 종료;}유형 시스템에 따르면 발신자는 DateFormaterror를 처리해야합니다.
value p = parseperiod (start, end); if (dateformaterror p) {...} else {...}또는 주어진 날짜 형식의 실제 문제를 신경 쓰지 않으면 (우리가 작업하는 초기화 코드에 해당 정보가 누락된다고 가정 할 때) dateformaterror 대신 NULL을 사용할 수 있습니다.
// 주어진 문자열이 유효한 날짜를 나타내지 않으면 null을 반환합니까? 구문 분석 (문자열 날짜) => ...; 공유 기간? parseperiod (String start, string end) => if (startDate = parsEdate (start), endDate = parsEdate (END)가 있습니다. 그 다음 기간 (startDate, EndDate) elle null; 공유 클래스 기간 (startDate, EndDate) {공유 날짜 시작 date; 공유 날짜 종료;}공장 기능을 사용하는 접근 방식은 일반적으로 검증 로직과 객체 초기화 사이에 더 나은 분리가 있기 때문에 가장 적게 말하는 것이 좋습니다. 이것은 Ceylon에서 특히 유용합니다. 여기서 컴파일러는 객체의 모든 영역에 한 번만 할당되도록하기 위해 객체 초기화 로직에 매우 엄격한 제한을 추가합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.