null 잘못된 디자인을 반환합니까? [닫은]
메서드에서 반환 된 null 값을 확인하는 것이 나쁜 디자인이라는 일부 목소리가 들렸습니다. 이에 대한 몇 가지 이유를 듣고 싶습니다.
의사 코드 :
variable x = object.method()
if (x is null) do something
null을 반환하지 않는 이유는 확인하지 않아도되므로 코드가 반환 값에 따라 다른 경로 를 따를 필요가 없다는 것 입니다. 이에 대한 자세한 정보를 제공 하는 널 오브젝트 패턴 을 확인하십시오 .
예를 들어, Collection을 반환하는 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.
}
}
그 이유가 있습니다.
에서 로버트 마틴 클린 코드 그는 널 (null)을 반환하는 것은 나쁜 대신 반환 할 수 있습니다 디자인, 말, 빈 배열이라고 씁니다. 예상 결과가 배열이므로 왜 안됩니까? 추가 조건없이 결과를 반복 할 수 있습니다. 정수이면 해시, 빈 해시이면 0이면 충분합니다. 기타
전제는 문제를 즉시 처리하도록 호출 코드를 강요하지 않는 것입니다. 호출 코드는 그들 자신과 관련이 없을 수도 있습니다. 그렇기 때문에 많은 경우에 예외가 nil보다 낫습니다.
null을 반환하는 좋은 사용법 :
- null이 유효한 기능적 결과 인 경우 : 예를 들면 다음과 같습니다. FindFirstObjectThatNeedsProcessing ()은 찾을 수없는 경우 null을 반환 할 수 있으며 호출자는 그에 따라 확인해야합니다.
나쁜 용도 : 다음과 같은 예외적 인 상황을 대체하거나 숨기려고합니다.
- catch (...) 및 null을 반환
- API 종속성 초기화 실패
- 디스크 공간 부족
- 유효하지 않은 입력 매개 변수 (프로그래밍 오류, 호출자가 입력을 삭제해야 함)
- 기타
이러한 경우에 예외를 던지는 것이 더 적합합니다.
- null 반환 값은 의미있는 오류 정보를 제공하지 않습니다.
- 즉시 발신자는 오류 상태를 처리 할 수 없습니다.
- 발신자가 null 결과를 확인한다고 보장 할 수 없습니다
그러나 다음과 같은 정상적인 프로그램 작동 조건을 처리하는 데 예외를 사용해서는 안됩니다.
- 잘못된 사용자 이름 / 비밀번호 (또는 사용자 제공 입력)
- 속보 루프 또는 로컬이 아닌 고 토스
예, 객체 지향 세계에서 NULL을 반환하는 것은 끔찍한 디자인 입니다. 간단히 말해서 NULL 사용법은 다음과 같습니다.
- 임시 오류 처리 (예외 대신)
- 모호한 의미
- 빠른 실패 대신 느리게
- 객체 사고 대신 컴퓨터 사고
- 변경 가능하고 불완전한 객체
: 자세한 설명이 블로그 게시물 확인 http://www.yegor256.com/2014/05/13/why-null-is-bad.html을 . 나의 책에서 더 많은 것은 우아한 객체들 , 섹션 4.1.
이것이 나쁜 디자인이라고 누가 말합니까?
null 검사는 일반적인 관행이며 권장되는 경우도 있습니다. 그렇지 않으면 어디서나 NullReferenceExceptions의 위험이 있습니다. 필요하지 않을 때 예외를 throw하는 것보다 오류를 정상적으로 처리하는 것이 좋습니다.
지금까지 말씀하신 내용에 의하면 충분한 정보가 없다고 생각합니다.
CreateWidget () 메소드에서 null을 반환하는 것은 좋지 않은 것 같습니다.
FindFooInBar () 메서드에서 null을 반환하는 것이 좋습니다.
It depends on the language you're using. If you're in a language like C# where the idiomatic way of indicating the lack of a value is to return null, then returning null is a good design if you don't have a value. Alternatively, in languages such as Haskell which idiomatically use the Maybe monad for this case, then returning null would be a bad design (if it were even possible).
If you read all the answers it becomes clear the answer to this question depends on the kind of method.
Firstly, when something exceptional happens (IOproblem etc), logically exceptions are thrown. When exactly something is exceptional is probably something for a different topic..
Whenever a method is expected to possibly have no results there are two categories:
- If it is possible to return a neutral value, do so.
Empty enumrables, strings etc are good examples - If such a neutral value does not exist, null should be returned.
As mentioned, the method is assumed to possibly have no result, so it is not exceptional, hence should not throw an exception. A neutral value is not possible (for example: 0 is not especially a neutral result, depending on the program)
Untill we have an official way to denote that a function can or cannot return null, I try to have a naming convention to denote so.
Just like you have the TrySomething() convention for methods that are expected to fail, I often name my methods SafeSomething() when the method returns a neutral result instead of null.
I'm not fully ok with the name yet, but couldn't come up with anything better. So I'm running with that for now.
Exceptions are for exceptional circumstances.
If your function is intended to find an attribute associated with a given object, and that object does has no such attribute, it may be appropriate to return null. If the object does not exist, throwing an exception may be more appropriate. If the function is meant to return a list of attributes, and there are none to return, returning an empty list makes sense - you're returning all zero attributes.
It's fine to return null if doing so is meaningful in some way:
public String getEmployeeName(int id){ ..}
In a case like this it's meaningful to return null if the id doesn't correspond to an existing entity, as it allows you to distinguish the case where no match was found from a legitimate error.
People may think this is bad because it can be abused as a "special" return value that indicates an error condition, which is not so good, a bit like returning error codes from a function but confusing because the user has to check the return for null, instead of catching the appropriate exceptions, e.g.
public Integer getId(...){
try{ ... ; return id; }
catch(Exception e){ return null;}
}
It's not necessarily a bad design - as with so many design decisions, it depends.
If the result of the method is something that would not have a good result in normal use, returning null is fine:
object x = GetObjectFromCache(); // return null if it's not in the cache
If there really should always be a non-null result, then it might be better to throw an exception:
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 /* ... */ {
}
I have a convention in this area that served me well
For single item queries:
Create...
returns a new instance, or throwsGet...
returns an expected existing instance, or throwsGetOrCreate...
returns an existing instance, or new instance if none exists, or throwsFind...
returns an existing instance, if it exists, ornull
For collection queries:
Get...
always returns a collection, which is empty if no matching[1] items are found
[1] given some criteria, explicit or implicit, given in the function name or as parameters.
For certain scenarios, you want to notice a failure as soon as it happens.
Checking against NULL and not asserting (for programmer errors) or throwing (for user or caller errors) in the failure case can mean that later crashes are harder to track down, because the original odd case wasn't found.
Moreover, ignoring errors can lead to security exploits. Perhaps the null-ness came from the fact that a buffer was overwritten or the like. Now, you are not crashing, which means the exploiter has a chance to execute in your code.
What alternatives do you see to returning null?
I see two cases:
- findAnItem( id ). What should this do if the item is not found
In this case we could: Return Null or throw a (checked) exception (or maybe create an item and return it)
- listItemsMatching (criteria) what should this return if nothing is found?
In this case we could return Null, return an empty list or throw an Exception.
I believe that return null may be less good than the alternatives becasue it requires the client to remember to check for null, programmers forget and code
x = find();
x.getField(); // bang null pointer exception
In Java, throwing a checked exception, RecordNotFoundException, allows the compiler to remind the client to deal with case.
I find that searches returning empty lists can be quite convenient - just populate the display with all the contents of the list, oh it's empty, the code "just works".
Sometimes, returning NULL is the right thing to do, but specifically when you're dealing with sequences of different sorts (arrays, lists, strings, what-have-you) it is probably better to return a zero-length sequence, as it leads to shorter and hopefully more understandable code, while not taking much more writing on API implementer's part.
Make them call another method after the fact to figure out if the previous call was null. ;-) Hey, it was good enough for JDBC
The base idea behind this thread is to program defensively. That is, code against the unexpected. There is an array of different replies:
Adamski suggests looking at Null Object Pattern, with that reply being up voted for that suggestion.
Michael Valenty also suggests a naming convention to tell the developer what may be expected. ZeroConcept suggests a proper use of Exception, if that is the reason for the NULL. And others.
If we make the "rule" that we always want to do defensive programming then we can see that these suggestions are valid.
But we have 2 development scenarios.
Classes "authored" by a developer: The Author
Classes "consumed" by another(maybe) developer: the Developer
Regardless of whether a class returns NULL for methods with a return value or not, the Developer will need to test if the object is valid.
If the developer cannot do this, then that Class/method is not deterministic. That is, if the "method call" to get the object does not do what it "advertises" (eg getEmployee) it has broken the contract.
As an author of a class, I always want to be as kind and defensive ( and deterministic) when creating a method.
So given that either NULL or the NULL OBJECT (eg if(employee as NullEmployee.ISVALID)) needs to be checked and that may need to happen with a collection of Employees, then the null object approach is the better approach.
But I also like Michael Valenty's suggestion of naming the method that MUST return null eg getEmployeeOrNull.
An Author who throws an exception is removing the choice for the developer to test the object's validity, which is very bad on a collection of objects, and forces the developer into exception handling when branching their consuming code.
As a developer consuming the class, I hope the author gives me the ability to avoid or program for the null situation that their class/methods may be faced with.
So as a developer I would program defensively against NULL from a method. If the author has given me a contract that always returns a object (NULL OBJECT always does) and that object has a method/property by which to test the validity of the object, then I would use that method/property to continue using the object, else the object is not valid and I cannot use it.
Bottom line is that the Author of the Class/Methods must provide mechanisms that a Developer can use in their defensive programming. That is, a clearer intention of the method.
The Developer should always use defensive programming to test the validity of the objects returned from another class/method.
regards
GregJF
Other options to this, are: returning some value that indicates success or not (or type of an error), but if you just need boolean value that will indicate success / fail, returning null for failure, and an object for success wouldn't be less correct, then returning true/false and getting the object through parameter.
Other approach would to to use exception to indicates failures, but here - there are actually many more voices, that say this is a BAD practice (as using exceptions may be convenient but has many disadvantages).
So I personally don't see anything bad in returning null as indication that something went wrong, and checking it later (to actually know if you have succeeded or not). Also, blindly thinking that your method will not return NULL, and then base your code on it, may lead to other, sometimes hard to find, errors (although in most cases it will just crash your system :), as you will reference to 0x00000000 sooner or later).
Unintended null functions can arise during the development of a complex programs, and like dead code, such occurrences indicate serious flaws in program structures.
A null function or method is often used as the default behavior of a revectorable function or overrideable method in an object framework.
Well, it sure depends of the purpose of the method ... Sometimes, a better choice would be to throw an exception. It all depends from case to case.
If the code is something like:
command = get_something_to_do()
if command: # if not Null
command.execute()
If you have a dummy object whose execute() method does nothing, and you return that instead of Null in the appropriate cases, you don't have to check for the Null case and can instead just do:
get_something_to_do().execute()
So, here the issue is not between checking for NULL vs. an exception, but is instead between the caller having to handle special non-cases differently (in whatever way) or not.
For my use case I needed to return a Map from method and then looking for a specific key. But if I return an empty Map, then it will lead to NullPointerException and then it wont be much different returning null instead of an empty Map. But from Java8 onward we could use Optional. The above is the very reason Optional concept was introduced.
G'day,
Returning NULL when you are unable to create a new object is standard practise for many APIs.
Why the hell it's bad design I have no idea.
Edit: This is true of languages where you don't have exceptions such as C where it has been the convention for many years.
HTH
'Avahappy,
참고URL : https://stackoverflow.com/questions/1274792/is-returning-null-bad-design
'Programing' 카테고리의 다른 글
Android Studio Gradle : 오류 : ': app : processDebugGoogleServices'태스크에 대한 실행에 실패했습니다. (0) | 2020.07.09 |
---|---|
markdown에 knitr를 사용하여 로컬 이미지의 크기를 설정하는 방법은 무엇입니까? (0) | 2020.07.09 |
RootViewController 스위치 전환 애니메이션 (0) | 2020.07.09 |
서비스 워커를 어떻게 제거합니까? (0) | 2020.07.09 |
특정 문자 뒤의 문자열 부분 제거 (0) | 2020.07.09 |