수업 디자인:색인화된 목록 또는 여러 속성?
-
06-07-2019 - |
문제
수업설계를 하다가 가끔 이런 일이 발생하는데..객체에 동일한 유형의 속성이 여러 개 있을 때.몇 가지 예를 들어보겠습니다.
사용자에게 여러 개의 주소가 있습니다.우리는 할 수 있다
IDictionary<string, Address> Addresses; // Addresses["BusinessAddress"];
또는
Address BusinessAddress;
Address ShippingAddress;
제품에는 다른 케이지별로 관련 제품이 있습니다.우리는 할 수 있다
IDictionary<string, IList<Product>> Related; // Related["Available"];
또는
IList<Product> Available;
IList<Product> Required;
사용자에게는 여러 역할이 할당되어 있습니다.우리는 할 수 있다
IList<Role> Roles;
또는
bool IsAdmin;
bool IsSales;
그렇다면 무엇이 더 좋은가요?IDictionary는 코드를 건드리지 않고도 새 주소 범주를 데이터베이스에 쉽게 추가할 수 있으므로 더 유연합니다.그러나 단점은 문자열을 사용하여 액세스한다는 것입니다.이것은 언제나 발생하기 쉬운 오류.단위 테스트나 다음과 같은 상수를 사용하여 이 문제를 해결할 수 있습니다.
public class ProductCategories { public static string Available = "Available"; }
그러나 "product.Related[ProductCategories.Available]"보다 "product.Available"을 읽는 것이 훨씬 더 나쁩니다.
ORM으로 매핑하는 것이 더 쉽고 더 나은 것과 같은 다른 고려 사항이 있습니다(예:NH절전 모드).
하지만 문제는 알려진 선호도가 있느냐는 것입니다.이 주제에 관한 기사 및/또는 책을 디자인하시겠습니까?여기 사람들이 경험한 실제 사례는 무엇입니까?
예를 들어, 두 세계를 결합할 수 있습니다.IList 및 bool IsAdmin이 "return Roles.Contain(Role("Admin"));"을 수행하도록 합니다.그러나 이것은 나에게 추악해 보입니다.
또는 IDictionary의 경우 유형당 주소를 1개 이상 가질 수 없습니다.그리고 만약 우리가 그렇게 한다면
IDictionary<string, IList<Address>>
이것은 배수가 필요하지 않은 단순한 주소의 경우 미쳐버릴 것입니다.그러나 MultipleAddress에 BillingAddress, ShippingAddress 및 IList를 사용하면 주소를 훨씬 더 세밀하게 제어할 수 있습니다.Intellisense 등을 사용합니다.
해결책
당신이 언급한 이후로 도메인 중심 설계 (DDD), 같은 제목의 책 에 대한 지침이 포함되어 있습니다. 의도를 드러내는 인터페이스.도메인 개체 사전을 갖는 것은 결코 의도를 드러내는 것이 아니므로 그 이유만으로도 사전을 사용하지 않는 것이 좋습니다.
사전은 대부분 호출자가 값을 추가하고 검색할 수 있는 API를 노출하거나 매우 유연한 상황을 처리할 수 있어야 하는 매우 일반적인 목적의 인프라 API에 사용되어야 합니다.
DDD의 경우는 그렇지 않습니다.클래스를 직접 작성하지 않았고 예제에서 사전 기반 주소 속성을 만났다고 가정해 보세요.어떤 유형의 주소가 포함되어 있는지 어떻게 알 수 있나요?구현 코드를 보거나 설명서를 읽어야 합니다.
반면에 BusinessAddress와 ShippingAddress 속성이 모두 있는 경우 API 소비자는 무엇을 사용할 수 있는지 즉시 알 수 있습니다.
내 생각에 당신이 생각하는 유연성은 유연성에 대한 잘못된 감각이라고 생각합니다. 왜냐하면 클라이언트 코드는 여전히 유연성이 필요하기 때문입니다. 알다 사전 항목을 사용하기 전에 사용할 수 있는 항목입니다.사전에 항목을 추가하는 것만큼 클래스에 새 속성을 추가하는 것도 쉽습니다.
때때로 모든 주소(또는 무엇이든)에 대해 반복해야 하기 때문에 사전(또는 목록)이 정말로 필요한 경우 다음과 같이 두 주소에 대한 열거자를 제공하는 읽기 전용 속성을 노출하여 이를 수행할 수 있습니다.
public Address BusinessAddress { get; set; }
public Address ShippingAddress { get; set; }
public IEnumerable<Address> Addresses
{
yield return this.BusinessAddress;
yield return this.ShippingAddress;
}
다른 팁
때에 따라 다르지.애플리케이션에서 사용자가 주소를 추가할 수 있도록 허용해야 한다면 반드시 다음과 같은 사전을 준비하세요. Address
예.