null 잘못된 디자인을 반환합니까? [닫은]


127

메서드에서 반환 된 null 값을 확인하는 것이 나쁜 디자인이라는 일부 목소리가 들렸습니다. 이에 대한 몇 가지 이유를 듣고 싶습니다.

의사 코드 :

variable x = object.method()
if (x is null) do something

13
정교하게 : 나쁜 사람들은 어디 있다고 말합니까? 연결?
jcollum

2
메서드가 제어 할 수있는 경우 null을 반환하지 않도록 단위 테스트를 수행 할 수 있습니다. 그렇지 않으면 호출 후 null인지 확인하는 것이 좋지 않은 이유를 알 수 없습니다. 이 메서드는 null을 반환하는 것이 좋지 않을 수도 있지만 코드를 보호해야합니다.
BlackTigerX

9
반환 할 데이터가 없기 때문에 예외를 발생시키는 것은 매우 성가신 일입니다. 정상적인 프로그램 흐름은 예외를 발생시키지 않아야합니다.
Thorarin

4
@David : 그것이 제가 실제로 말한 것입니다. 메소드가 데이터를 리턴해야하지만 아무것도 없으면, 이는 또한 무언가 잘못되었음을 의미합니다. 그것은 정상적인 프로그램 흐름이 아닙니다 :)
Thorarin

2
@Thorarin : "정상적인"프로그램 흐름은 상당히 확장 가능한 개념입니다. 실제로 논쟁에 대한 확실한 근거는 아닙니다.
Tomislav Nakic-Alfirevic

답변:


206

null을 반환하지 않는 이유는 확인하지 않아도되므로 코드가 반환 값에 따라 다른 경로따를 필요가 없다는 것 입니다. 널 오브젝트 패턴 을 확인하고 싶을 수도 있습니다. 대한 자세한 정보를 제공 .

예를 들어, 컬렉션을 반환하는 Java에서 메소드를 정의하려는 경우 일반적으로 Collections.emptyList()클라이언트 코드가 더 깨끗하다는 의미에서 null 대신 빈 컬렉션을 반환하는 것을 선호합니다 . 예 :

Collection<? extends Item> c = getItems(); // Will never return null.

for (Item item : c) { // Will not enter the loop if c is empty.
  // Process item.
}

...보다 깨끗한 것 :

Collection<? extends Item> c = getItems(); // Could potentially return null.

// Two possible code paths now so harder to test.
if (c != null) {
  for (Item item : c) {
    // Process item.
  }
}

6
예, null을 반환하고 클라이언트가 사건을 처리하기를 바랍니다.
djna

10
빈 컨테이너 (또는 문자열)의 대체물로 사용될 때 null을 반환하는 것이 미친다는 데 행복하게 동의합니다. 그러나 일반적인 경우는 아닙니다.
MSalters

2
Null Object Pattern도 +1입니다. 또한 실제로 null을 반환하려고 할 때 getCustomerOrNull ()과 같은 메서드의 이름을 명시 적으로 지정했습니다. 독자가 구현을보고 싶지 않을 때 메소드의 이름이 적절하다고 생각합니다.
Mike Valenty

4
주석 '// 2 개의 가능한 코드 경로'가 올바르지 않습니다. 두 가지 코드 경로가 있습니다. 그러나 첫 번째 예제에서 null Collection 개체를 사용하면 'null'코드 경로가 더 짧습니다. 그래도 여전히 두 개의 경로가 있으며 여전히 두 개의 경로를 테스트해야합니다.
Frerich Raabe가

1
@MSalters- OO 언어의 모든 변수 null는 "컨테이너"이며 객체에 대한 포인터가 0 개 또는 1 개 있습니다. (그런 Maybe경우 Haskell의 모델이 어떻게 만들어 졌는지 확실히 알 수 있습니다.)
Andrzej Doyle

71

그 이유가 있습니다.

로버트 마틴 클린 코드 그는 널 (null)을 반환하는 것은 나쁜 대신 반환 할 수 있습니다 디자인, 말, 빈 배열이라고 씁니다. 예상 결과가 배열이므로 왜 안됩니까? 추가 조건없이 결과를 반복 할 수 있습니다. 정수이면 해시, 빈 해시이면 0이면 충분합니다. 기타

전제는 문제를 즉시 처리하도록 호출 코드를 강요하지 않는 것입니다. 호출 코드는 그들 자신과 관련이 없을 수도 있습니다. 그렇기 때문에 많은 경우에 예외가 nil보다 낫습니다.


2
: 이것은이 답변에서 언급 한 널 개체 패턴입니다 stackoverflow.com/questions/1274792/...
스콧 도먼

여기서 아이디어는 오류가 발생하면 정상적으로 반환 할 객체 유형의 빈 / 빈 버전을 반환한다는 것입니다. 예를 들어 빈 배열이나 문자열은 이러한 경우에 작동합니다. NULL이 본질적으로 빈 포인터이므로 일반적으로 포인터를 반환 할 때 "NULL"을 반환하는 것이 적절합니다. 일반적으로 해시를 반환하는 함수에서 오류가 발생하면 NULL을 반환하면 혼란 스러울 수 있습니다. 어떤 언어는 이것을 다른 언어보다 잘 처리하지만 일반적으로 일관성이 가장 좋습니다.
bta

오류가 어떻게 든 흐름을 제어하거나 (좋은 방법은 아님) API 또는 인터페이스에서 추상화되지 않는 한 반드시 오류를 반환하지는 않습니다. 오류는 잡기로 결정한 모든 수준으로 전파되므로 호출 컨텍스트에서 처리 할 필요가 없습니다. 기본적으로 null-object-pattern-friendly입니다.
Max Chernyak

불행히도, 호출 코드는 항상 빈 컬렉션의 경우를 고려하지는 않습니다 (널 케이스를 고려하지 않는 것처럼). 문제가 될 수도 있고 아닐 수도 있습니다.
Sridhar Sarnobat

38

null을 반환하는 좋은 사용법 :

  • null이 유효한 기능적 결과 인 경우 : 예를 들면 다음과 같습니다. FindFirstObjectThatNeedsProcessing ()은 찾을 수없는 경우 null을 반환 할 수 있으며 호출자는 그에 따라 확인해야합니다.

나쁜 용도 : 다음과 같은 예외적 인 상황을 대체하거나 숨기려고합니다.

  • catch (...) 및 null을 반환
  • API 종속성 초기화 실패
  • 디스크 공간 부족
  • 유효하지 않은 입력 매개 변수 (프로그래밍 오류, 호출자가 입력을 삭제해야 함)
  • 기타

이러한 경우에 예외를 던지는 것이 더 적합합니다.

  • null 반환 값은 의미있는 오류 정보를 제공하지 않습니다.
  • 즉시 발신자는 오류 상태를 처리 할 수 ​​없습니다.
  • 발신자가 null 결과를 확인한다고 보장 할 수 없습니다

그러나 다음과 같은 정상적인 프로그램 작동 조건을 처리하는 데 예외를 사용해서는 안됩니다.

  • 잘못된 사용자 이름 / 비밀번호 (또는 사용자 제공 입력)
  • 속보 루프 또는 로컬이 아닌 고 토스

7
"잘못된 사용자 이름"은 예외의 좋은 원인 인 것 같습니다.
Thilo

11
유효하지 않은 로그인 / 암호를 입력하는 사용자는 정상적인 프로그램 작동의 일부인 예외적 인 조건으로 취급되어서는 안됩니다. 그러나 인증 시스템이 응답하지 않는 경우 (예 : 활성 디렉토리) 예외적 인 조건입니다.
ZeroConcept


2
나는 그것이 달려 있다고 말하고 싶다 : 좋아 boolean login(String,String)보인다 .AuthenticationContext createAuthContext(String,String) throws AuthenticationException
sfussenegger

1
예를 들어, 처리가 필요한 첫 번째 객체가없는 경우 해당 사례를 처리하는 두 가지 합리적인 방법이 있습니다. 첫 번째는 Null Object 패턴입니다. 존재하지 않는 클래스 버전을 나타내는 최종 서브 클래스를 작성하십시오. 합리적인 기본값이 있으며 넌센스 액션이 요청되면 예외가 발생합니다. 다른 기술은 옵션입니다. 이것이 Java8 및 Scala에서 사용 가능한 것입니다. 이 중 하나는 개발자의 의도를 보여줍니다. null은 의미가 너무 많아 의도를 표시 할 수 없습니다. ** 의도 표시 **는 코드의 가장 중요한 측면입니다.
scott m gardner

29

예, 객체 지향 세계에서 NULL을 반환하는 것은 끔찍한 디자인 입니다. 간단히 말해서 NULL 사용법은 다음과 같습니다.

  • 임시 오류 처리 (예외 대신)
  • 모호한 의미
  • 빠른 실패 대신 느리게
  • 객체 사고 대신 컴퓨터 사고
  • 변경 가능하고 불완전한 객체

: 자세한 설명이 블로그 게시물 확인 http://www.yegor256.com/2014/05/13/why-null-is-bad.html을 . 나의 책에서 더 많은 것은 우아한 객체들 , 섹션 4.1.


2
나는 강력하게 동의합니다. 나는 'whitewash'지연 전술 인 것처럼 보이는 null 객체 패턴조차 좋아하지 않습니다. 방법이 항상 성공한다고 가정하거나 그렇지 않을 수 있습니다. 항상 성공한다면 던져라. 이 성공하지 못할 경우 소비자가 예, 알 수 있도록 다음 방법을 설계 bool TryGetBlah(out blah)하거나 FirstOrNull()또는 MatchOrFallback(T fallbackValue).
Luke Puplett 2016 년

나도 null을 반환하는 것을 좋아하지 않습니다. 근본 원인을 증상과 분리하여 디버깅을 더욱 어렵게합니다. 예외를 던지거나 (실패), 먼저 부울을 리턴하는 검사기 메소드를 호출하십시오 (예 : isEmpty()true). 사람들은 두 번째 주장에 대해 성능이 떨어 졌다고 주장합니다. 그러나 Unix Philosophy가 말했듯이 "기계 시간보다 인간의 시간을 소중하게 생각합니다"(즉, 성능이 느리면 개발자가 코드를 디버깅하는 것보다 허위 오류가 발생합니다).
Sridhar Sarnobat 님이

22

이것이 나쁜 디자인이라고 누가 말합니까?

null 검사는 일반적인 관행이며 권장되는 경우도 있습니다. 필요하지 않을 때 예외를 throw하는 것보다 오류를 정상적으로 처리하는 것이 좋습니다.


11
+1. 현장에서 완화 될 수있는 문제에 대한 예외를 던지는 코드는 나를 슬프게합니다.
jkeys

6
코더가 null을 확인하는 것을 잊어 버린 후 신비한 null 포인터 예외를 얻는 것이 얼마나 슬픈 일입니까? 컴파일러가 오류 조건을 처리하지 않았다는 것을 사용자에게 상기시켜주는 검사 예외는 클래스의 코딩 오류를 피합니다.
djna

3
@ djna : 이것도 슬픈 것 같지만 null을 확인하는 "잊어 버린"동일한 유형의 코더가 확인 된 예외를 처리 할 때 종종 삼키는 결과가 있음을 알았습니다.
랜디가

5
널 검사가없는 것보다 빈 캐치 블록이 있는지 확인하는 것이 더 쉽습니다.
Preston

20
@Preston : 나는 매우 동의하지 않습니다. null 검사가 없으면 충돌이 발생했을 때 즉시 발견됩니다. 삼킨 예외는 수년간 신비 롭고 미묘한 오류를 전파 할 수 있습니다 ...
Beska

18

지금까지 말씀하신 내용에 의하면 충분한 정보가 없다고 생각합니다.

CreateWidget () 메소드에서 null을 반환하는 것은 좋지 않은 것 같습니다.

FindFooInBar () 메서드에서 null을 반환하는 것이 좋습니다.


4
내 규칙과 비슷합니다. 단일 항목 쿼리- Create... 새 인스턴스를 반환 하거나 던집니다 . Get...예상되는 기존 인스턴스를 반환 하거나 throw합니다 . GetOrCreate...기존 인스턴스를 반환하거나 존재하지 않는 경우 새 인스턴스를 반환 하거나 throw합니다 . Find...존재하는 경우, 기존 인스턴스를 반환 하거나null . 컬렉션 쿼리의 경우- Get... 항상 컬렉션을 반환합니다. 일치하는 항목이 없으면 비어 있습니다.
Johann Gerell

yegor256 & hakuinin의 답변에 주어진 이유로 인해 NULL이 잘못되었습니다. 유효하지만 빈 객체를 반환하면 추론이 간단 해집니다.
Rob11311


10

사용중인 언어에 따라 다릅니다. 값이 없음을 나타내는 관용적 방법이 null을 반환하는 C #과 같은 언어 인 경우 값이 없으면 null을 반환하는 것이 좋습니다. 또는이 경우에 Maybe 모나드를 관용적으로 사용하는 Haskell과 같은 언어에서는 null을 반환하는 것이 좋지 않은 디자인입니다 (가능한 경우).


2
모나드 언급으로 +1 nullC # 및 Java와 같은 언어 의 정의 가 종종 과부하되어 도메인에서 의미가 있음을 알았습니다 . null언어 사양에서 키워드 를 찾으면 단순히 "잘못된 포인터"를 의미합니다. 그것은 문제 영역에서 아무것도 의미하지 않습니다.
MattDavey

문제가 "결 측값" null인지 "초기화되지 않은 " 것인지 모르는 경우null
CervEd

5

모든 답변을 읽으면이 질문에 대한 답변은 방법의 종류에 따라 다릅니다.

첫째, 예외적 인 상황 (IO 문제 등)이 발생하면 논리적으로 예외가 발생합니다. 정확히 무언가가 예외적 인 경우 아마도 다른 주제에 대한 것일 수 있습니다.

분석법에 결과가 없을 것으로 예상 될 때마다 두 가지 범주가 있습니다.

  • 중립 값 을 반환 할 수 있으면 그렇게하십시오 .
    빈 열거 형, 문자열 등이 좋은 예입니다.
  • 그러한 중립 값이 존재하지 않으면 null을 반환해야합니다 .
    언급 한 바와 같이,이 방법은 결과가 없을 것으로 예상되므로 예외가 아니므로 예외를 발생시키지 않아야합니다. 중립 값을 사용할 수 없습니다 (예 : 0은 프로그램에 따라 특히 중립 결과가 아닙니다)

함수가 null을 반환 할 수 있거나 반환 할 수 없다는 공식적인 방법이있을 때까지는 명명 규칙을 지정하려고합니다. 실패 할 것으로 예상되는 메소드에 대해 Try Something () 규칙
이있는 것처럼 , 종종 메소드 이름을 Safe Something ()으로 지정합니다. 방법이 null 대신 중립적 인 결과를 반환 할 때입니다.

나는 아직 그 이름을 완전히 알지 못했지만 더 나은 것을 만들 수 없었습니다. 그래서 나는 지금 그것을 가지고 달리고 있습니다.


4

이 분야에서 저를 잘 섬기는 대회가 있습니다

단일 항목 쿼리의 경우 :

  • Create...새 인스턴스를 반환 하거나
  • Get...예상되는 기존 인스턴스를 반환 하거나
  • GetOrCreate...기존 인스턴스를 반환하거나 존재하지 않는 경우 새 인스턴스를 반환 하거나
  • Find...존재하는 경우 기존 인스턴스를 반환 하거나null

수집 쿼리의 경우 :

  • Get... 일치하는 [1] 개의 항목이 없으면 항상 비어있는 컬렉션을 반환합니다.

[1] 함수 이름 또는 매개 변수로 주어진 명시 적 또는 암시 적 기준이 제공됩니다.


찾을 수없는 경우 왜 GetOne과 FindOne이 다르게 반환됩니까?
Vladimir Vukanac

차이점을 설명했습니다. 나는 그것이 거기에있을 것으로 기대할Get 때 사용 하므로 거기에 없다면 오류가 발생하고 던져집니다-반환 값을 확인할 필요가 없습니다. 나는 그것이 있는지 여부를 정말로 모른다면 사용합니다-그런 다음 반환 값을 확인해야합니다. Find
Johann Gerell

3

예외는 예외 상황에 대한 것입니다.

함수가 주어진 객체와 관련된 속성을 찾으려고하고 해당 객체에 그러한 속성이없는 경우 null을 반환하는 것이 적절할 수 있습니다. 객체가 존재하지 않으면 예외를 던지는 것이 더 적절할 수 있습니다. 함수가 속성 목록을 반환하는 것이지만 반환 할 것이 없으면 빈 목록을 반환하는 것이 의미가 있습니다. 모든 속성을 0으로 반환하는 것입니다.


1
값이없는 속성 을 사용 하려고 하면 예외가됩니다. (귀하의 스펙에서 속성이 선택적이라고 가정합니다.) 값이 설정되어 있는지 확인하는 별도의 방법이 있습니다.
Preston

3

어떤 식 으로든 의미가있는 경우 null을 반환하는 것이 좋습니다.

public String getEmployeeName(int id){ ..}

이와 같은 경우 ID가 기존 엔티티와 일치하지 않으면 null을 반환하는 것이 의미가 있습니다. 정상적인 오류와 일치하는 것이없는 경우를 구별 할 수 있기 때문입니다.

사람들은 이것이 오류 조건을 나타내는 "특별한"반환 값으로 남용 될 수 있기 때문에 이것이 잘못되었다고 생각할 수 있습니다. 이는 좋지 않은 기능에서 오류 코드를 반환하는 것과 약간 같지만 사용자가 반환을 확인해야하기 때문에 혼란 스럽습니다. 적절한 예외를 잡는 대신에 null

public Integer getId(...){
   try{ ... ; return id; }
   catch(Exception e){ return null;}
}

3
예. 오류가 발생하면 예외를 처리하십시오.
David Thornley

3
예외가 필요한 경우입니다. 존재하지 않는 직원의 이름을 요청하면 문제가 발생합니다.
Thorarin

나는 그것이 약간 리터럴이라고 생각합니다. Thorarin-당신은 확실히 내 예제로 떨릴 수 있지만 일치하는 값을 반환하는 함수의 인스턴스를 상상할 수 있거나 일치하지 않으면 null을 상상할 수 있습니다. 해시 테이블의 키에서 값을 얻는 방법은 무엇입니까? (처음에 그 예를 생각해 보았을 것입니다).
Steve B.

1
존재하지 않는 키에 대해 null을 반환하는 해시 테이블이 잘못되었습니다. 그렇게하면 자동으로 일관성이없는 코드없이 null을 값으로 저장할 수 없습니다.
RHSeeger

3

많은 디자인 결정과 마찬가지로 반드시 나쁜 디자인은 아닙니다.

메소드의 결과가 정상적인 사용에서 좋은 결과를 얻지 못하는 것이라면 null을 반환하는 것이 좋습니다.

object x = GetObjectFromCache();   // return null if it's not in the cache

항상 널이 아닌 결과가 있어야하는 경우 예외를 처리하는 것이 좋습니다.

try {
   Controller c = GetController();    // the controller object is central to 
                                      //   the application. If we don't get one, 
                                      //   we're fubar

   // it's likely that it's OK to not have the try/catch since you won't 
   // be able to really handle the problem here
}
catch /* ... */ {
}

2
진단 오류를 바로 기록 할 수 있지만 예외를 다시 발생시킬 수 있습니다. 언젠가 처음 실패 데이터 캡처는 매우 유용 할 수 있습니다.
djna

또는 메시지 문자열의 진단 정보를 사용하여 RuntimeException에서 예외를 랩하십시오. 정보를 함께 보관하십시오.
Thorbjørn Ravn Andersen

이제 (2018 년) 더 이상 동의 할 수 없으며,이 경우 귀국을 선호해야합니다Optional<>
Piotr Müller

2

특정 시나리오의 경우 실패가 발생하자마자 실패를 확인하려고합니다.

실패 사례에서 NULL을 확인하고 (프로그래머 오류의 경우) 던지거나 (사용자 또는 호출자 오류의 경우) 던지는 경우 원래의 이상한 경우를 찾을 수 없기 때문에 나중에 충돌을 추적하기가 더 어려울 수 있습니다.

또한 오류를 무시하면 보안 악용으로 이어질 수 있습니다. 아마도 null-ness는 버퍼를 덮어 쓴다는 사실에서 비롯된 것입니다. 이제 크래시 가 발생 하지 않습니다 . 이는 악용자가 코드에서 실행할 수있는 기회를 의미합니다.


2

null을 반환하는 대안은 무엇입니까?

두 가지 경우가 있습니다.

  • findAnItem (id). 아이템을 찾지 못하면 어떻게해야합니까

이 경우에는 다음을 수행 할 수 있습니다. Null을 반환하거나 (확인 된) 예외를 throw하거나 항목을 만들어 반환 할 수 있습니다.

  • listItemsMatching (기준) 아무것도 발견되지 않으면 어떻게 리턴해야합니까?

이 경우 Null을 반환하거나 빈 목록을 반환하거나 예외를 throw 할 수 있습니다.

나는 null을 반환하는 것이 클라이언트가 null을 확인해야한다는 것을 기억해야하기 때문에 대안보다 좋지 않을 수 있다고 생각합니다. 프로그래머는 잊어 버리고 코드를 작성해야합니다.

x = find();
x.getField();  // bang null pointer exception

Java에서 확인 된 예외 인 RecordNotFoundException을 발생 시키면 컴파일러가 클라이언트에게 사례를 처리하도록 상기시킬 수 있습니다.

빈 목록을 반환하는 검색이 매우 편리하다는 것을 알았습니다. 목록의 모든 내용으로 디스플레이를 채우십시오. 오, 비어 있습니다. 코드는 "작동합니다".


3
프로그램의 정상적인 흐름 중에 발생할 것으로 예상되는 조건을 나타 내기 위해 예외를 던지면 try {x = find ()} catch (RecordNotFound e) {// do stuff}와 같은 코드가 실제로 추악합니다.
quant_dev

빈 목록을 반환하는 것이 좋은 솔루션이지만 메서드가 목록을 반환 할 수있는 컨텍스트에있는 경우에만 가능합니다. "findById"상황의 경우 널을 리턴해야합니다. RecordNotFound 예외가 마음에 들지 않습니다.
Thilo

이것이 우리 의견의 차이입니다. 내 눈에는 x = find (); 사이에 아름다움에 큰 차이가 없습니다. if (x = null) {work} else {stuff}하고 catch를 시도하십시오. 필요한 경우 코드 정확성을 위해 아름다움을 희생 할 준비가되었습니다. 내 인생에서 너무 자주 반환 값을 확인하지 않은 코드가 발생합니다.
djna

1

때로는 NULL을 반환하는 것이 옳은 일이지만, 구체적으로 다른 종류의 배열 (배열, 목록, 문자열, 무엇을 가지고 있는지)을 다룰 때 길이가 0 인 시퀀스를 반환하는 것이 좋습니다. API 구현 자에 대해 더 많은 글을 쓰지 않으면 서 더 짧고 희망적으로 이해하기 쉬운 코드로 연결됩니다.



1

이 스레드의 기본 아이디어는 방어 적으로 프로그래밍하는 것입니다. 즉, 예상치 못한 코드입니다. 다른 답글이 있습니다 :

아담 스키 는 Null Object Pattern (Null 개체 패턴)을 검토 할 것을 제안합니다.

Michael Valenty 는 또한 개발자에게 예상 할 수있는 것을 알려주기위한 명명 규칙을 제안합니다. ZeroConcept 는 NULL의 이유 인 경우 Exception의 올바른 사용을 제안합니다. 다른 사람.

우리가 항상 방어 프로그래밍을하고 싶은 "규칙"을 만들면 이러한 제안이 유효한 것을 볼 수 있습니다.

그러나 우리에게는 두 가지 개발 시나리오가 있습니다.

개발자가 "저작 한"클래스 : 저자

다른 (아마도) 개발자가 "소비 한"클래스 : 개발자

반환 값이있는 메서드에 대해 클래스가 NULL을 반환하는지 여부에 관계없이 개발자는 개체가 유효한지 테스트해야합니다.

개발자가이를 수행 할 수없는 경우 해당 클래스 / 방법은 결정적이지 않습니다. 즉, 객체를 얻기위한 "메소드 호출"이 "광고"(예 : getEmployee)를 수행하지 않으면 계약을 위반 한 것입니다.

수업의 저자로서, 나는 항상 메소드를 만들 때 친절하고 방어 적이며 결정론 적이기를 원합니다.

따라서 NULL 또는 NULL OBJECT (예 : if (employee as NullEmployee.ISVALID))를 확인해야하고 Employees 컬렉션에서 발생할 수있는 경우 null 개체 접근 방식이 더 좋습니다.

그러나 마이클 발레 티 (Michael Valenty)의 getEmployeeOrNull과 같이 null을 반환 해야하는 메서드의 이름을 제안하는 것도 좋습니다.

예외를 던지는 작성자는 개발자가 객체의 유효성을 테스트 할 수있는 선택권을 제거하는 것입니다. 이는 객체 모음에서 매우 나쁘고 개발자가 소비 코드를 분기 할 때 예외 처리를 강요합니다.

클래스를 소비하는 개발자로서 필자는 클래스 / 메소드가 직면 할 수있는 null 상황을 피하거나 프로그램 할 수있는 기능을 제공하기를 희망한다.

따라서 개발자는 메소드에서 NULL에 대해 방어 적으로 프로그래밍합니다. 저자가 항상 객체를 반환하는 계약 (NULL OBJECT가 항상 수행하는 계약)을 제공하고 해당 객체에 객체의 유효성을 테스트하는 메소드 / 프로퍼티가있는 경우 해당 메소드 / 프로퍼티를 사용하여 객체를 계속 사용합니다. 그렇지 않으면 객체가 유효하지 않아 사용할 수 없습니다.

결론은 클래스 / 메소드 작성자가 개발자가 방어 프로그래밍에 사용할 수있는 메커니즘을 제공해야한다는 것입니다. 즉, 방법의 명확한 의도입니다.

개발자는 항상 방어 적 프로그래밍을 사용하여 다른 클래스 / 방법에서 반환 된 객체의 유효성을 테스트해야합니다.

문안 인사

그레그


0

이것에 대한 다른 옵션은 다음과 같습니다 : 성공 여부를 나타내는 일부 값을 반환 (또는 오류 유형)하지만 성공 / 실패를 나타내는 부울 값이 필요한 경우 실패에 대해 null을 반환하고 성공에 대한 객체는 그렇지 않습니다 덜 정확한 다음 true / false를 반환하고 매개 변수를 통해 객체를 가져옵니다.
다른 접근법은 예외를 사용하여 실패를 표시하지만 여기에는 실제로 더 많은 음성이 있습니다. 예를 들어 이것이 나쁜 습관이라고 말합니다 (예외를 사용하는 것이 편리하지만 많은 단점이 있음).
그래서 개인적으로 무언가 잘못되었다는 표시로 null을 반환하고 나중에 확인하여 실제로 성공했는지 여부를 확인하는 데 나쁜 점은 없습니다. 또한, 맹목적으로 메소드가 NULL을 반환하지 않는다고 생각하고 코드를 기반으로하고 때로는 찾기 어려운 다른 오류가 발생할 수 있습니다 (대부분의 경우 시스템을 중단시킬 수는 있음). 조만간 0x00000000).


0

의도하지 않은 널 함수는 복잡한 프로그램을 개발하는 동안 발생할 수 있으며 데드 코드와 같이 이러한 발생은 프로그램 구조에 심각한 결함이 있음을 나타냅니다.

null 함수 또는 메소드는 종종 객체 프레임 워크에서 revectorable 함수 또는 재정의 가능한 메소드의 기본 동작으로 사용됩니다.

Null_ 함수 @wikipedia


0

글쎄, 그것은 확실히 방법의 목적에 달려 있습니다 ... 때로는 더 나은 선택은 예외를 던지는 것입니다. 그것은 모두 경우에 따라 다릅니다.


0

코드가 다음과 같은 경우 :

command = get_something_to_do()

if command:  # if not Null
    command.execute()

execute () 메소드가 아무것도하지 않는 더미 객체가 있고 적절한 경우 Null 대신 반환하면 Null 케이스를 확인할 필요가 없으며 대신 수행 할 수 있습니다.

get_something_to_do().execute()

따라서 여기서 문제는 NULL 검사와 예외 검사 사이가 아니라 호출자가 특수한 경우를 다르게 처리 해야하는 경우 (어떤 방식 으로든) 사이입니다.


0

유스 케이스의 경우 메소드에서 Map을 반환 한 다음 특정 키를 찾아야했습니다. 그러나 빈 맵을 반환하면 NullPointerException이 발생하고 빈 맵 대신 null을 반환하는 것과 크게 다르지 않습니다. 그러나 Java8부터는 Optional을 사용할 수 있습니다 . 이것이 바로 선택적 개념이 도입 된 이유입니다.


-3

G'day,

새 객체를 만들 수 없을 때 NULL을 반환하는 것은 많은 API의 표준 사례입니다.

도대체 왜 나쁜 디자인인지 모르겠다.

편집 : 이것은 몇 년 동안 관습이었던 C와 같이 예외가없는 언어의 경우에 해당됩니다.

HTH

'아바 해피,


2
객체를 만들 수 없으면 실제로 예외를 발생시켜야합니다. 일부 쿼리와 일치하는 객체를 찾을 수 없으면 null을 반환하는 것이 좋습니다.
Thilo

@Thilo, C에서 어떻게하는지 보여 주면 가장 관심이있을 것이다.
Rob Wells

@RobWells C는 객체 지향 언어 아니지만,이 질문은 "OOP"로 태그되어
yegor256

@ yegor256 당신이 맞아요. 그리고 나는 원래 OOP 태그를 놓쳤다. 그러나 BS가 말했듯이 C ++의 클래스는 일부 추가 멤버 함수가 추가되고 멋진 메모리 관리가 내부적으로 발생하는 구조체 일뿐입니다. 그러나 API가 구조체를 반환한다고 생각되면 구조체를 만들 수 없을 때 NUL을 반환하는 것이 종종 관례입니다.
Rob Wells
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.