델파이에서 싱글턴을 한다고 하면 보통 다음과 같은 소스를 많이 제시한다.
이런 소스의 문제는
1. 종료할 때 해제가 안 된다는 점
2. 여전히 Create가 가능하다는 점
이 있다.
첫째의 경우 싱글턴의 특성상 누수의 양이 많아서 문제가 되는 건 아니다. 어차피 인스턴스는 하나만 존재하기 때문이다.
그러나 ReportMemoryLeaksOnShutdown같은 옵션을 쓴다면 경고가 신경쓰이며 잘못하면 진짜 누수를 찾지 못하게 될 수도 있다.
둘째의 경우는 그 자체만으로도 치명적이다.
다른 언어 싱글턴 구현을 보고 구현하는 경우 private 생성자 Create를 만들게 마련인데, 델파이에선 그렇게 해도 public constructor Create는 그대로 남아있다.
public으로 선언된 TObject.Create는 private 생성자로는 가릴 수가 없기 때문이다!
결론적으로 소스는 다음과 같이 구현하면 위의 두 문제를 해결할 수 있다 (위의 원본 소스에서 수정하였다).
물론 Destroy를 직접 부르거나 FreeAndNil로 제거하는 등의 상황에서는 참사를 막지 못하겠지만, 적어도 일반적인 상황에서 나타날 수 있는 실수는 많은 부분 막을 수 있다.
[snippet slug=delphi-singleton lang=pascal]
원래 생성자와 파괴자 코드에 들어가야 할 코드는 //Write constructor, //Write destructor로 시작하는 부분에 각각 넣어주면 된다.
사실 FreeAndNil같은 것도 플래그 하나를 더 넣으면 막을 수 있겠지만 이 상태도 이미 행사 코드가 너무 길어서 넣지 않았다.
행사 코드가 상당히 길어서 마음에 들지는 않지만 이 정도는 되어야 타 언어 싱글턴 구현에 가까운 편의성을 지니게 되니, 매우 안타깝다.