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.