당신의 질문입니다.
그러나 내 순진함에서 비명을 지르는 경우가 있습니다. 때로는 가치가 없을 수도 있습니다!
거기 당신과 함께 완전히 탑승. 그러나 잠시 후 몇 가지주의 할 점이 있습니다. 그러나 먼저 :
널은 사악하므로 가능할 때마다 피해야합니다.
나는 이것이 잘 의도되었지만 지나치게 일반화 된 진술이라고 생각합니다.
널은 악이 아니다. 반 패턴이 아닙니다. 그것들은 모든 비용으로 피해야 할 것이 아닙니다. 그러나 널 (null) 확인에 실패하여 널이 오류 가 발생하기 쉽습니다 .
그러나 null을 확인하지 못하면 null이 본질적으로 잘못 사용되었음을 증명하는 방법을 이해하지 못합니다.
null이 악의 인 경우는 배열 인덱스와 C ++ 포인터도 마찬가지입니다. 그들은 아니다. 그들은 발로 쉽게 쏠 수 있지만 모든 비용을 피할 수는 없습니다.
이 답변의 나머지 부분에서, 나는 "null은 악하다"라는 의도를보다 미묘한 " null은 책임감있게 다루어야한다 "에 맞추 겠다 .
당신의 솔루션.
전역 규칙으로 null을 사용하는 것에 대한 귀하의 의견에 동의하지만; 이 특정 경우에 null을 사용하는 것에 동의하지 않습니다.
아래 피드백을 요약하면 상속과 다형성의 목적을 오해하고있는 것입니다. 널 (null)을 사용한다는 당신의 주장은 타당하지만, 다른 방법이 왜 나쁜지에 대한 당신의 "증거"는 상속의 오용에 기반을두고 있으며, 당신의 포인트가 널 (null) 문제와는 관련이 없습니다.
대부분의 업데이트에는 당연히 플레이어가 연결되어 있습니다. 결국 어떤 플레이어가이 턴을했는지 알아야합니다. 그러나 일부 업데이트에는 플레이어와 의미있게 연결된 플레이어가 없을 수 있습니다.
이러한 업데이트가 의미가 다른 경우 (업데이트 된 경우) 두 가지 별도의 업데이트 유형이 필요합니다.
예를 들어 메시지를 고려하십시오. 오류 메시지와 IM 채팅 메시지가 있습니다. 그러나 매우 유사한 데이터 (문자열 메시지 및 발신자)를 포함 할 수 있지만 동일한 방식으로 작동하지 않습니다. 서로 다른 클래스로 별도로 사용해야합니다.
지금하고있는 일은 Player 속성의 null-ness에 따라 두 가지 업데이트 유형을 효과적으로 구분하는 것입니다. 이는 오류 코드의 존재 여부에 따라 IM 메시지와 오류 메시지를 결정하는 것과 같습니다. 작동하지만 최선의 방법은 아닙니다.
- JS 코드는 이제 Player가없는 객체를 정의 된 속성으로받습니다. 두 경우 모두 값이 있는지 또는 없는지 확인해야하기 때문에 null 인 경우와 같습니다.
당신의 주장은 다형성의 잘못에 의존합니다. 당신이 반환하는 방법이 있다면 GameUpdate
객체를, 일반적으로 지금까지 구분하는 신경 안 GameUpdate
, PlayerGameUpdate
또는 NewlyDevelopedGameUpdate
.
기본 클래스는 완전히 작동하는 계약을 가져야합니다. 즉, 해당 속성은 파생 클래스가 아니라 기본 클래스에 정의되어 있습니다 (즉, 이러한 기본 속성 의 값 은 파생 클래스에서 재정의 될 수 있음).
이것은 당신의 논증을 무디게합니다. 모범 사례에서는 GameUpdate
객체에 플레이어가 있거나 없는 것을 신경 쓰지 않아야합니다 . 의 Player
속성에 액세스하려는 경우 GameUpdate
비논리적 인 일을하는 것입니다.
C #과 같은 유형이 지정된 언어는 단순히 속성이 없기 때문에 속성에 액세스하려고 시도 조차 할 수 없습니다. Javascript는 접근 방식에서 상당히 여유가 없으며 사전 컴파일이 필요하지 않으므로 수정하지 않아도되어 런타임에 폭발 할 수 있습니다.Player
GameUpdate
GameUpdate
- 또 다른 nullable 필드가 GameUpdate 클래스에 추가되면 다중 상속을 사용 하여이 desing을 계속할 수 있어야하지만 MI는 자체적으로 (보다 숙련 된 프로그래머에 따르면) 악의적이며 더 중요한 것은 C #이 아닙니다. 사용하지 못하도록하십시오.
nullable 속성을 추가하여 클래스를 만들면 안됩니다. 기능적으로 고유 한 유형의 게임 업데이트를 기반으로 클래스를 작성해야 합니다 .
일반적으로 null 문제를 피하는 방법은 무엇입니까?
가치가 없다는 것을 의미있게 표현할 수있는 방법에 대해 자세히 설명하는 것이 적절하다고 생각합니다. 이것은 특정 순서로 솔루션 (또는 나쁜 접근 방식) 모음입니다.
1. 어쨌든 null을 사용하십시오.
이것이 가장 쉬운 방법입니다. 그러나 수많은 null 검사에 서명하고 null 참조 예외 문제를 해결하지 못한 경우 (그러지 않을 경우)
2. null이 아닌 의미없는 값을 사용하십시오.
간단한 예는 indexOf()
다음과 같습니다.
"abcde".indexOf("b"); // 1
"abcde".indexOf("f"); // -1
대신에 null
당신은 얻는다 -1
. 기술적 인 수준에서 이것은 유효한 정수 값입니다. 그러나, 음의 값은이다 무의미한 인덱스가 양의 정수가 될 것으로 예상된다대로 대답은.
논리적으로, 이것은 반환 유형이 의미있게 반환 될 수있는 것보다 더 많은 값을 허용하는 경우에만 사용할 수 있습니다 (indexOf = 양의 정수; int = 음수 및 양의 정수)
참조 유형의 경우이 원칙을 계속 적용 할 수 있습니다. 예를 들어 정수 ID의 엔터티가있는 경우 null이 아닌 ID가 -1로 설정된 더미 객체를 반환 할 수 있습니다.
객체를 실제로 사용할 수 있는지 여부를 측정 할 수있는 "더미 상태"를 정의하기 만하면됩니다.
문자열 값을 제어하지 않으면 미리 정해진 문자열 값에 의존해서는 안됩니다. 빈 개체를 반환 할 때 사용자 이름을 "null"로 설정하는 것을 고려할 수 있지만 Christopher Null이 서비스에 등록 할 때 문제가 발생합니다 .
3. 대신 예외를 던져라.
아뇨 논리적 흐름에 대한 예외를 처리해서는 안됩니다.
즉, (nullreference) 예외를 숨기고 싶지 않고 적절한 예외를 표시하는 경우가 있습니다. 예를 들면 다음과 같습니다.
var existingPerson = personRepository.GetById(123);
이것은 PersonNotFoundException
ID가 123 인 사람이 없을 때 (또는 유사한) 것을 던질 수 있습니다 .
분명히 이것은 항목을 찾지 못하면 추가 처리가 불가능한 경우에만 허용됩니다. 항목을 찾을 수없고 응용 프로그램을 계속할 수 있으면 예외를 던져서는 안됩니다 . 나는 이것을 충분히 강조 할 수 없다.