피할 수 있으면 어느 쪽도 사용하지 마십시오. 옵션 유형, 튜플 또는 전용 합계 유형을 반환하는 팩토리 함수를 사용하십시오. 다시 말해, 기본이 아닌 보장 된 값과 다른 유형의 잠재적으로 기본값이있는 값을 나타냅니다.
먼저 desiderata를 나열한 다음 몇 가지 언어 (C ++, OCaml, Python)로이를 표현할 수있는 방법에 대해 생각해 봅시다.
- 컴파일 타임에 기본 객체의 원치 않는 사용을 잡습니다.
- 코드를 읽는 동안 주어진 값이 기본값이 될 수 있는지 여부를 분명히하십시오.
- 해당되는 경우 유형 당 한 번씩 합리적인 기본값을 선택하십시오 . 모든 통화 사이트에서 잠재적으로 다른 기본값을 선택 하지 마십시오 .
- 정적 분석 도구 또는 사람이
grep
잠재적 인 실수를 쉽게 찾을 수 있도록합니다 .
- 일부 응용 프로그램의 경우 예기치 않게 기본값이 지정되면 프로그램이 정상적으로 계속 진행되어야합니다. 다른 응용 프로그램의 경우, 기본값으로 정보를 제공하면 프로그램이 즉시 중지되어야합니다.
Null Object Pattern과 Null 포인터 사이의 장력은 (5)에서 비롯된 것 같습니다. 그래도 오류를 조기에 감지 할 수 있다면 (5)는 약해집니다.
이 언어를 언어별로 고려해 봅시다 :
C ++
제 생각에는 C ++ 클래스는 일반적으로 라이브러리와의 상호 작용을 용이하게하고 컨테이너에서 클래스를 사용하기 쉽기 때문에 기본 구성 가능해야합니다. 또한 어떤 수퍼 클래스 생성자를 호출 할 필요가 없으므로 상속을 단순화합니다.
그러나 이는 유형 값이 MyClass
"기본 상태" 인지 여부를 확실하게 알 수 없음을 의미합니다 . bool nonempty
런타임시 표면 기본값에 유사하거나 유사한 필드를 넣는 것 외에도 사용자가 확인하도록 강제하는 새로운 인스턴스를 생성MyClass
하는 것이 가장 좋습니다 .
나는를 반환하는 공장 기능을 사용하는 것이 좋습니다 것 std::optional<MyClass>
, std::pair<bool, MyClass>
A를 또는 r 값 참조를 std::unique_ptr<MyClass>
가능합니다.
팩토리 함수가 default-constructed와는 다른 일종의 "자리 표시 자"상태를 리턴 MyClass
하도록하려면 a를 사용하고 std::pair
함수가이를 수행하는지 문서화해야합니다.
팩토리 기능에 고유 한 이름이 있으면 이름을 쉽게 작성하고 grep
구할 수 있습니다. 그러나 grep
프로그래머 가 팩토리 기능을 사용해야했지만 그렇지 않은 경우에는 어렵습니다 .
오캄
OCaml과 같은 언어를 사용하는 경우 option
유형 (OCaml 표준 라이브러리) 또는 either
유형 (표준 라이브러리는 아니지만 자신 만의 롤링)을 사용할 수 있습니다. 또는 defaultable
유형 (나는 용어를 구성하고 있습니다 defaultable
).
type 'a option =
| None
| Some of 'a
type ('a, 'b) either =
| Left of 'a
| Right of 'b
type 'a defaultable =
| Default of 'a
| Real of 'a
defaultable
사용자가 패턴 일치를 추출해야 'a
하고 쌍의 첫 번째 요소를 무시할 수 없기 때문에 위에 표시된 것처럼 A 는 쌍보다 낫습니다 .
등가의 defaultable
위와 같은 유형은 C ++를 사용하여 사용될 수있다 std::variant
동일한 유형의 두 인스턴스하지만 일부 std::variant
두 종류가 동일한 경우 API를 사용할 수 없게된다. 또한 std::variant
형식 생성자의 이름이 지정되지 않았기 때문에 이상한 사용입니다 .
파이썬
어쨌든 파이썬에 대한 컴파일 타임 검사는 없습니다. 그러나 동적으로 유형을 지정하면 일반적으로 컴파일러를 대체하기 위해 특정 유형의 자리 표시 자 인스턴스가 필요한 상황이 없습니다.
기본 인스턴스를 만들어야 할 때 예외를 던지는 것이 좋습니다.
그것이 받아 들일 수 없다면, 나는 공장 함수에서 DefaultedMyClass
상속 하고 그것을 MyClass
반환하는 것을 만드는 것이 좋습니다 . 필요한 경우 기본 인스턴스에서 "스터 빙 아웃 (stubbing out)"기능 측면에서 유연성을 확보합니다.