열거 형에 특별한 값“ALL”을 갖는 것이 좋은 방법입니까?


11

마이크로 서비스 환경에서 새로운 서비스를 개발 중입니다. REST 서비스입니다. 간단히하기 위해 경로는 다음과 같습니다. / historyBooks

그리고이 경로에 대한 POST 방법은 새로운 역사 책을 만듭니다.

역사 책은 역사의 하나 이상의 시대를 다루고 있다고 가정하자.

간결성을 위해 다음과 같은 인류 역사 시대 만 가정 해 봅시다.

  • 고대
  • 포스트 클래식
  • 현대

내 코드에서는으로 표현하고 싶습니다 enum.

메소드 본문 (페이로드)은 JSON 형식이며 필드 이름을 포함해야합니다 eras. 이 필드는 era이 책에서 다루는 값 목록입니다 .

몸은 다음과 같이 보일 수 있습니다.

{
  "name": "From the cave to Einstein - a brief history review",
  "author": "Foo Bar",
  "eras": ["Ancient", "Post Classical", "Modern"]
}

이 특정 서비스에서 비즈니스 논리는
다음과 같습니다. 입력에 시대가 없다면이 책은 모든 시대 를 다루는 것으로 간주됩니다 .

API 검토에서 제안은 다음과 같습니다. 시대 열거에 대해
다른 값을 포함 ALL하여 모든 시대가 포함되어 있음을 명시 적으로 나타냅니다.

나는 그것이 몇 가지 장단점이 있다고 생각합니다.

장점 :

명시 적 입력

단점 :

목록에 두 가지 항목이 제공되면 다음 ALL과 같이 말하십시오 Ancient-신청서에서 무엇을 가져 옵니까? 나는 그 추측 ALL다른 값을 오버라이드 (override) 할 필요가 있지만, 새로운 비즈니스 로직입니다.

특정 시대를 다루는 책에 대해 쿼리를 실행하면 모든 시대를 다루는 책을 어떻게 표현할 수 있습니까? 경우 ALL도 (같은 논리를 사용하여) 출력에 사용되는, 그것은 해석하는 소비자의 책임 ALL으로가 ["Ancient", "Post Classical", "Modern"].

내 질문

나는 새로운 것을 갖는 ALL것이 전혀없는 것보다 더 혼란을 야기 한다고 생각 합니다.

어떻게 생각해? 이 ALL값 을 추가 하거나 값없이 API를 유지 하시겠습니까 ?


7
원자 시대를 추가하기로 결정하면 어떻게됩니까? "모든"시대를 다루는 책이 마술처럼 새로운 콘텐츠를 얻습니까? 책 내용에 대해 거짓말하기 시작합니까? 당신은 모든 것을 겪고 업데이트합니까? 일부 책에 실제로 원자 시대에 관한 내용이 이미 있다면 이는 사소한 일이 아닙니다.
8bittree

답변:


13

사용 가능한 시대가 호출 응용 프로그램에 사용 가능한지 여부에 따라 다릅니다. 사용자가 관심있는 항목을 선택할 수 있도록 설정되어있을 것입니다.이 경우 "모두"옵션을 제공하는 것은 프론트 엔드 문제입니다. 그것이 나라면 "모든"옵션이 아닌 모든 시대의 목록을 보내 게 될 것입니다. 그렇지 않은 경우 "ALL"옵션이 필요하고 위험을 감수하면 프런트 엔드가 이해할 수없는 시대부터 물건을 되 찾을 수 있습니다.

다른 옵션과 함께 ALL은 충돌하는 요청을 얻을 수 있음을 의미합니다. 한 가지 더 고려해야 할 사항은 "ALL"을 전달할 수 있고 다른 열거 형은 포함이 아닌 제외가됩니다. 예를 들어 "ALL", "고대"는 "고대인을 제외한 모든 것"을 의미합니다. 그것은 일종의 의미가 있지만 분명히 UI는 복잡한 것일 수 있습니다.

TL; DR; 대부분의 "ALL"은 UI 기능이며 모호함없이 서비스 수준에서 동일한 것을 달성 할 수 있으므로 수행하지 마십시오.


6

입력에 시대가 없다면이 책은 모든 시대를 다루는 것으로 간주됩니다.

이것은 또한 특별한 '모두'사례를 갖는 것은 나쁜 IMHO입니다. 가능한 경우 API를 명시해야합니다. '실제로 모든 것을 의미하는 것은 없습니다'와 같은 특수 사례가 있다는 것은 API를 사용하는 사람이 모든 특수 사례를 알아야하거나 'ALL'사례와 마찬가지로 의도 및 / 또는 결과가 모호한 요청을 가져와야 함을 의미합니다.

특수한 경우는 종종 사용자 입력이 유효한지 여부를 확인하고 요청을 올바르게 처리하는 측면에서 더 복잡한 코드를 생성합니다.


1

범주 형 변수의 경우 와일드 카드를 "모두"같은 수준으로 설정하지 않습니다.

기간 동안 2 단계 검색 기준이있는 것 같습니다.

  1. 부울, is_selective?
  2. 특정 카테고리의 설정, 분리

호출자는 (false, ignore) 또는 (true, { 'ancient', 'modern'})을 지정할 수 있습니다.

또는 빈 세트를 와일드 카드로 해석하도록 선택할 수 있으며 선택하지 않음을 나타냅니다.

특정 경우, 연속 변수, 연도, 잘 알려진 몇 가지 값으로 이산 된 것처럼 들리며 실제로 원하는 것은 간격 산술을하는 것입니다. 따라서 쿼리는 (시작, 끝) 기간을 수용하고 열거 형은 그러한 속성을 편리하게 제공 할 수 있습니다.


1

tl; dr
구현의 로컬 데이터 구조에 관한 실제 질문에 대해서는 다음과 같은 결론에 동의합니다. 모든 시대의 특별한 가치를 피하십시오. 대부분의 실수와 복잡성을 유발할 수 있기 때문입니다. 그러나 특히 최종 사용자 UI와 직렬화 된 페이로드 데이터는 다른 이야기 일 수 있습니다.

로컬 데이터 구조

타입 시스템 관점에서 이것을 보자. 기본적으로 열거 형은 @JH답변 에서 이미 지적한 것처럼 특정 범주 (열거)의 분리 세트를 정의하는 유형입니다 . 열거 형의 변수에는 해당 범주 중 하나가 정확하게 포함됩니다. 열거 자 값의 모음을 나타내려면 두 번째 유형이 필요합니다.

// C++-inspired pseudo-code
enum Era { ancient, post_classical, modern };
using Eras = Collection<Era>;

all열거는 함께 두 종류의 매쉬 때문에 더 - 이동하지 않습니다. 단일 카테고리가 아니라 가능한 모든 카테고리의 모음입니다.

엄격하게 실용적인 수준에서 모든 종류의 특수 값을 처리하면 구현이 복잡해 지므로 오류가 발생할 가능성이 높아집니다. 실제 의미와 일치하도록 모든 곳에서 특수한 경우 또는 포장을 풀어야하기 때문입니다. 아, 그리고 가능한 모든 열거자를 명시 적으로 수집하는 것은 어떻습니까? 언제 어디에서 이것을 특별한 all가치로 접어야합니까? 전혀 무너져 야합니까?

내가 선호하는 아키텍처는 코드 의 모든 시대 를 표현하지 않는 것 입니다. 여기에는 all열거 자뿐만 아니라 모든 시대를 의미하는 빈 컬렉션도 포함됩니다 . 다른 변장에서와 똑같은 특별한 경우입니다.

목록에 두 항목이 제공되면 ALL과 Ancient라고 말하십시오. 응용 프로그램에서 무엇을 가져 옵니까? [...]

API 사양에서 모든 시대 마커가 항상 자체적으로 표시되어야 함 을 명시하고 싶습니다 . 그런 다음 계약 위반으로이를 거부합니다. 그러나 모든 시대 가 구현과 비즈니스 로직 을 어떻게 복잡하게 만드는지 보여주는 좋은 예입니다 .

주요 문제는 특별한 가치와 그 기본 의미 사이의 변환 규칙을 지정해야한다는 것입니다. 그런 다음 API를 사용하는 모든 사용자가 해당 규칙을 올바르게 구현해야합니다. 저에 냉소는 그것의 질문이 아니다라고 나에게 이야기 하면 누군가가 오해하지만, 단순히 .

직렬화 된 데이터 (JSON)

원래 여기에는 읽기 전용 쿼리와 "eras"목록의 다른 역할을 수정하는 방법에 대한 전체 섹션이 있습니다 . 그러나 결국 KISS 때문에 삭제했습니다. 열거 형 / 수집 규칙은 JSON 데이터에 적합하지 않으므로 일관된 상태를 유지하는 것이 가장 간단한 솔루션입니다.

최종 사용자를위한 UI

UI와 기본 데이터 구조 사이에 데이터 변환이 있다고 가정합니다. MVC-ish 아키텍처가 있기 때문일 것입니다. 따라서 사용자에게 가장 편리하고 직관적 인 것을 사용하십시오. 에 그의 대답 @Markus은 요일에 대한 다양한 선택 옵션이있는 좋은 예를 주었다.


1

나는 새로운 ALL을 갖는 것이 전혀없는 것보다 더 많은 혼란을 야기한다고 생각합니다.

예.

컬렉션 관점에서 생각하면 : 전체 컬렉션이 있습니다. 그리고 해당 컬렉션의 하위 집합 만 원할 때마다 요소가이 하위 집합의 요소로 간주 될 때 일종의 filtercondition 을 제공해야합니다 . 그리고 ALL경우, 어떤 필터가 적용되지 않을 때 아니다 "는 filtercondition이가 ALL" .

입력에 시대가 없다면이 책은 모든 시대를 다루는 것으로 간주됩니다.

나는 그것을 뒤집어 놓을 것이다 :이 책은 특정 시대를 다루지 않는다 .

이것은 쿼리 관점에서도 일관성이 있습니다.

시대를 선택하지 않으면 모든 책이 반환됩니다 (빈 필드가있는 책 포함). 시대를 선택하면 선택한 시대의 도서 만 반환됩니다. 특별한 시대와 일반 도서를 모두 검색하면 예상치 못한 결과가 발생합니다.

ALL-카테고리를 추가 할 수있는 유일한 점 은 사용자 편의를위한 것입니다. "Everything"대신 "Nothing"을 선택하면 더 짜증이 날 수 있습니다.


0

나는 최근에 기본 스케줄러를 구현했으며 @LoztInSpace에서 이미 언급했듯이 대부분은 UI 설탕입니다.

사용자 인터페이스는 옵션 중 하나를 선택할 때 사용자가 달성 할 수있는 내용이 명확해야합니다.

내 경우에는 평일을 선택해야합니다. "모두"외에도 "근무일"과 "주말"을 옵션으로 추가했습니다. 각 옵션을 선택하면 나중에 사용할 때 옵션이 포함되므로 포함하지 않으려는 날짜는 수동으로 선택 해제해야합니다.

기술적으로 이것은 사용자가 "평일"을 선택하면 UI에 5 개의 확인란이 선택되고 열거 형에는 "근무일"값이 사용됩니다. 확인란 중 하나를 선택 취소하면 "근무일"값이 남은 4 일의 비트 맵으로 대체됩니다.

옵션의 일부를 사용하여 모든 것을 포함하고 동시에 충돌을 피하고 UI가 사용자에게 의미가 있는지 확인하기 위해 무언가를 제외하지 마십시오.

사용자가 "All"에 포함 된 개념 (일주일 내내)을 이해하거나 중요하지 않은 경우 (아마존의 모든 범주 검색)를 사용하면 "All"옵션을 사용하는 것이 좋습니다.


0

ALL 열거 형을 명시 적으로 수행한다는 아이디어가 마음에 들지만 플래그로 설정하려고합니다.

const enum = {
    ALL: { value: 0 },
    ANCIENT: { name: 'Ancient', value: 1 },
    POST_CLASSICAL: { name: 'Post Classical', value: 2 },
    MODERN: { name: 'Modern', value: 4 }
}

flagon 과 같은 라이브러리를 사용 하거나 모든 값을 선택할 때 비트 단위 조작 으로 수동 재생하는 대신 ALL을 사용합니다.

열거 형의 값은 항상 이전의 두 배 여야합니다. 그리고 온 전성 검사를 위해 열거 형을 제거해서는 안되지만 비활성화 할 수는 있지만 항상 비활성화 된 코드를 ALL의 일부로 계산하도록 코드를 조정하십시오.

대신 NONE 플래그를 사용하고 나중에 비즈니스가 변경 될 경우 NONE을 사용할 때 수행 할 작업을 클라이언트가 결정하도록 할 수 있습니다.

이 구현을 수행하면 enun을 전달하는 대신 선택한 값의 합계를 대신 전달합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.