유형 추론이 아니었다면 불변 속성뿐만 아니라 구현을 통해 "두 세계의 장점을 모두 얻을" 수 있었습니다. FluentThing
API에 정의된 클래스이지만 변경 가능한 또 다른 클래스는 FluentThingInternalUseOnly
확장 변환을 지원하는 FluentThing
.Fluent 회원들은 FluentThing
새로운 인스턴스를 생성할 것입니다. FluentThingInternalUseOnly
후자의 유형을 반환 유형으로 사용합니다.회원들 FluentThingInternalUseOnly
작동하고 돌아올 것입니다. this
.
누군가가 이렇게 말했다면 FluentThing newThing = oldFluentThing.WithThis(4).WithThat(3).WithOther(57);
, WithThis
방법은 새로운 것을 만들 것입니다 FluentThingInternalUseOnly
.동일한 인스턴스가 수정되어 반환됩니다. WithThat
그리고 WithOther
;그런 다음 해당 데이터는 새 데이터베이스에 복사됩니다. FluentThing
그 참조는 다음 위치에 저장됩니다. newThing
.
이 접근 방식의 주요 문제점은 누군가가 다음과 같이 말한다면 dim newThing = oldFluentThing.WithThis(3);
, 그 다음에 newThing
불변에 대한 참조를 보유하지 않습니다 FluentThing
, 그러나 변경 가능 FluentThingInternalUseOnly
, 그리고 그 것은 그것에 대한 참조가 지속되었다는 것을 알 수 있는 방법이 없습니다.
개념적으로 필요한 것은 FluentThingInternalUseOnly
공개 함수의 반환 유형으로 사용할 수 있을 만큼 충분히 공개되어야 하지만, 외부 코드에서 해당 유형의 변수를 선언하는 것을 허용할 만큼 공개되어서는 안 됩니다.불행하게도 나는 이것을 할 수 있는 어떤 방법도 모른다. Obsolete()
태그가 가능할 수도 있습니다.
그렇지 않고, 작동되는 객체가 복잡하지만 작업이 간단한 경우, 가장 좋은 방법은 유창한 인터페이스 메서드가 호출된 객체에 대한 참조를 보유하는 객체를 반환하도록 하는 것입니다. 해당 객체에 대해 수행되어야 하며[유창한 메소드를 연결하면 효과적으로 연결된 목록을 구축할 수 있음] 모든 적절한 변경 사항이 적용된 객체에 대한 지연 평가 참조가 수행되어야 합니다.누군가가 전화했다면 newThing = myThing.WithBar(3).WithBoz(9).WithBam(42)
, 각 단계에서 새로운 래퍼 객체가 생성되고 첫 번째 시도에서는 newThing
뭔가를 구축해야 할 것입니다 Thing
세 가지 변경 사항이 적용된 인스턴스가 있지만 원본은 myThing
그대로 유지되며 새로운 인스턴스를 하나만 만들면 됩니다. Thing
세 개보다는.