เป็นวิธีปฏิบัติที่ดีหรือไม่ที่จะมีค่าพิเศษ“ ALL” ใน enum


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สำหรับยุค enum เพื่อระบุอย่างชัดเจนว่ามีการครอบคลุมยุคทั้งหมด

ฉันคิดว่ามันมีข้อดีและข้อเสีย

ข้อดี:

อินพุตที่ชัดเจน

จุดด้อย:

หากมีการจัดเตรียมสองรายการในรายการพูดALLและAncient- สิ่งที่จะนำมาจากแอปพลิเคชัน ฉันเดาว่าALLควรจะแทนที่ค่าอื่น ๆ แต่นั่นคือตรรกะทางธุรกิจใหม่

ถ้าฉันเรียกใช้คิวรีสำหรับหนังสือที่ครอบคลุมยุคเฉพาะฉันจะแสดงหนังสือที่ครอบคลุมยุคทั้งหมดได้อย่างไร หากALLยังใช้สำหรับการส่งออก (โดยใช้ตรรกะเดียวกัน) แล้วมันเป็นความรับผิดชอบของผู้บริโภคที่จะตีความเป็นALL["Ancient", "Post Classical", "Modern"]

คำถามของฉัน

ฉันคิดว่าการมีสิ่งใหม่ ๆALLทำให้เกิดความสับสนมากกว่าที่จะไม่มีเลย

คุณคิดอย่างไร? คุณจะเพิ่มALLมูลค่านี้หรือรักษา API ของคุณโดยไม่ได้


7
จะเกิดอะไรขึ้นถ้าคุณตัดสินใจที่จะเพิ่มยุคอะตอม หนังสือที่ครอบคลุมยุค "ทั้งหมด" ได้รับเนื้อหาใหม่อย่างน่าอัศจรรย์หรือไม่? คุณเริ่มโกหกเกี่ยวกับเนื้อหาของหนังสือหรือไม่ คุณผ่านและอัปเดตทุกอย่างหรือไม่ นั่นอาจไม่ใช่เรื่องไร้สาระถ้าหนังสือบางเล่มมีเนื้อหาเกี่ยวกับยุคอะตอมอยู่แล้ว
8bittree

คำตอบ:


13

ขึ้นอยู่กับว่ายุคที่มีอยู่ของคุณพร้อมใช้งานสำหรับแอปพลิเคชันการโทรหรือไม่ ผู้ใช้สามารถเลือกสิ่งที่พวกเขาสนใจหากเป็นเช่นนั้นผู้ใช้จะสามารถเลือกตัวเลือก "ALL" ได้ ถ้าเป็นฉันนั่นจะส่งรายชื่อของยุคทั้งหมดแทนที่จะเป็นตัวเลือก "ทั้งหมด" ถ้าไม่เช่นนั้นคุณจำเป็นต้องมีตัวเลือก "ทั้งหมด" และดำเนินการเสี่ยงแล้วว่าส่วนหน้าจะได้รับสิ่งต่าง ๆ จากยุคที่ไม่เข้าใจ

ในขณะที่คุณชี้ให้เห็นทั้งหมดพร้อมตัวเลือกอื่น ๆ หมายความว่าคุณสามารถรับคำขอที่ขัดแย้งกันได้ ข้อควรพิจารณาอีกประการหนึ่งคือคุณสามารถผ่าน "ALL" จากนั้น Enums อื่น ๆ จะกลายเป็นข้อยกเว้นมากกว่าการรวมเช่น "ALL", "Ancient" หมายถึง "ทุกอย่างยกเว้นโบราณ" นั่นทำให้รู้สึกบางอย่าง แต่เห็นได้ชัดว่า UI นั้นจะต้องสะท้อนให้เห็นถึงสิ่งที่อาจจะซับซ้อนกว่า

TL; DR; ส่วนใหญ่ "ALL" เป็นความดีของ UI และคุณสามารถบรรลุสิ่งเดียวกันในระดับบริการโดยไม่มีความกำกวมดังนั้นอย่าทำเช่นนั้น


6

หากไม่มียุคระบุไว้ในข้อมูลเข้าดังนั้นหนังสือเล่มนี้จะถือว่าครอบคลุมทุกยุคทุกสมัย

สิ่งนี้และยังมีกรณีพิเศษ 'ALL' ซึ่งเป็น IMHO ที่ไม่ดี - API ของคุณควรชัดเจนหากเป็นไปได้ การมีกรณีพิเศษเช่น 'ไม่มีอะไรหมายถึงทุกอย่าง' หมายความว่าทุกคนที่ใช้ API ของคุณจะต้องรู้ว่ากรณีพิเศษของคุณทั้งหมดหรือเช่นกรณี 'ALL' นำไปสู่คำขอที่เจตนาและ / หรือผลลัพธ์ที่คลุมเครือ

กรณีพิเศษก็มักจะนำไปสู่รหัสที่ซับซ้อนมากขึ้นทั้งในแง่ของการตรวจสอบว่าการป้อนข้อมูลของผู้ใช้ถูกต้องหรือไม่และการจัดการคำขอได้อย่างถูกต้อง


1

สำหรับตัวแปรเด็ดขาดฉันจะหลีกเลี่ยงการใส่สัญลักษณ์ตัวแทน "ทั้งหมด" ในระดับเดียวกัน

ดูเหมือนว่าคุณมีเกณฑ์การค้นหาสองระดับสำหรับช่วงเวลา:

  1. บูลีน, is_selective?
  2. ชุดแยกส่วนที่เฉพาะเจาะจง

ผู้โทรสามารถระบุ (false, ละเว้น) หรือ (จริง, {'Ancient', 'modern'})

หรือคุณสามารถเลือกตีความชุดที่ว่างเปล่าเป็นสัญลักษณ์แทนมันหมายถึง Not Selective

สำหรับกรณีเฉพาะของคุณดูเหมือนว่าคุณจะมีตัวแปรต่อเนื่องปีที่แยกออกเป็นค่าที่รู้จักกันดีและสิ่งที่คุณต้องการคือการทำเลขคณิตช่วงเวลา ดังนั้นข้อความค้นหาของคุณจะยอมรับช่วง (เริ่มต้น, สิ้นสุด) ของปีและ enums สามารถจัดหาแอตทริบิวต์ดังกล่าวได้อย่างสะดวก


1

tl; dr
สำหรับคำถามจริงของคุณ - เกี่ยวกับโครงสร้างข้อมูลท้องถิ่นในการนำไปใช้ - ฉันเห็นด้วยกับข้อสรุปของคุณ: หลีกเลี่ยงค่าพิเศษทั้งหมดเนื่องจากส่วนใหญ่จะเพิ่มความซับซ้อนและโอกาสในการทำผิดพลาด อย่างไรก็ตามโดยเฉพาะอย่างยิ่ง UI ของผู้ใช้และข้อมูล payload ที่ต่อเนื่องกันอาจมีเรื่องราวที่แตกต่างกัน

โครงสร้างข้อมูลท้องถิ่น

ลองดูที่นี่จากมุมมองของระบบประเภท โดยทั่วไป enum เป็นประเภทที่กำหนดชุดเนื่องของหมวดหมู่เฉพาะ (enumerators) ที่ชี้เป็นแล้วออกมาในคำตอบโดย @JH ตัวแปรประเภท enum ถือเป็นหนึ่งในประเภทเหล่านั้นทั้งหมด หากคุณต้องการแสดงชุดของค่าตัวแจงนับคุณต้องมีประเภทที่สอง:

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

ตัวallแจงนับเป็นสิ่งที่ไม่ต้องดำเนินการเพราะจะผสานทั้งสองประเภทเข้าด้วยกัน มันไม่ใช่หมวดหมู่เดียว แต่เป็นคอลเลกชันของหมวดหมู่ที่เป็นไปได้ทั้งหมด

ในระดับปฏิบัติอย่างเคร่งครัดการจัดการกับค่าพิเศษชนิดใดก็ตามทำให้การติดตั้งนั้นซับซ้อนและทำให้โอกาสในการเกิดข้อผิดพลาดสูงขึ้น - เพราะคุณต้องกรณีพิเศษทุกที่หรือแกะมันออกมาให้ตรงกับความหมายที่แท้จริงของมัน โอ้และสิ่งที่เกี่ยวกับคอลเลกชันที่ชัดเจนของตัวแจงนับที่เป็นไปได้ทั้งหมด สิ่งนี้ควรยุบเมื่อใดและที่ไหนในallค่าพิเศษ? มันควรจะถูกยุบเลยเหรอ?

สถาปัตยกรรมที่ฉันต้องการคือไม่มีการแสดงช่วงเวลาทั้งหมดในรหัส ที่มีการallแจงนับ แต่นี้ยังมีคอลเลกชันที่ว่างเปล่าหมายถึงทุกยุคทุกสมัย มันเป็นกรณีพิเศษที่เหมือนกันเพียงแค่ในการปลอมตัวที่แตกต่างกัน

หากมีสองรายการในรายการให้พูดทั้งหมดและเก่า - สิ่งที่จะนำมาจากแอปพลิเคชัน? [ ... ]

ฉันจะระบุในข้อมูลจำเพาะของ API ว่าเครื่องหมายลบทั้งหมดต้องปรากฏด้วยตัวของมันเองเพราะการมีบางอย่างที่อยู่ด้านบนไม่เหมาะสม ถ้าอย่างนั้นฉันก็ปฏิเสธว่านี่เป็นการละเมิดสัญญา แต่มันก็เป็นตัวอย่างที่ดีว่ายุคทั้งหมดนั้นซับซ้อนทั้งการนำไปใช้และตรรกะทางธุรกิจอย่างไร

ปัญหาหลักคือคุณถูกบังคับให้ระบุกฎสำหรับการแปลงระหว่างค่าพิเศษและความหมายพื้นฐาน จากนั้นคุณและทุกคนที่ใช้ API จะต้องปฏิบัติตามกฎเหล่านั้นอย่างถูกต้อง ถากถางในฉันบอกฉันว่ามันไม่ได้เป็นคำถามของถ้าคนที่จะได้รับมันผิด แต่เพียงเมื่อ

ข้อมูลต่อเนื่อง (JSON)

แต่เดิมฉันมีทั้งส่วนที่นี่เกี่ยวกับการแก้ไขการค้นหาแบบอ่านอย่างเดียวและบทบาทที่แตกต่างกันสำหรับ"eras"รายการ แต่ในที่สุดฉันก็ลบเพราะ KISS กฎสำหรับ enum / การรวบรวมไม่ได้ไม่มีเหตุผลสำหรับข้อมูล JSON ดังนั้นการรักษาสิ่งต่าง ๆ ให้สอดคล้องจึงเป็นทางออกที่ง่ายที่สุด

UI สำหรับผู้ใช้

ฉันคิดว่าจะมีการแปลงข้อมูลระหว่าง UI และโครงสร้างข้อมูลพื้นฐานส่วนใหญ่เนื่องจากคุณมีสถาปัตยกรรม MVC-ish บางประเภท ดังนั้นใช้สิ่งที่สะดวกที่สุดและใช้งานง่ายสำหรับผู้ใช้ ในคำตอบของเขา @Markusให้ตัวอย่างที่ยอดเยี่ยมกับตัวเลือกการเลือกที่แตกต่างกันสำหรับวันในสัปดาห์


1

ฉันคิดว่าการมี ALL ใหม่ทำให้เกิดความสับสนมากกว่าการไม่มีเลย

ใช่.

หากคุณคิดจากมุมมองของคอลเลคชั่น: คุณมีของสะสมทั้งหมด และทุกครั้งที่คุณต้องการเซตย่อยของคอลเลกชันนั้นคุณจะต้องระบุประเภทของการกรองเมื่อองค์ประกอบถูกพิจารณาว่าเป็นองค์ประกอบของชุดย่อยนี้ และALLเป็นกรณีที่เมื่อไม่มีตัวกรองถูกนำไปใช้ไม่ได้"filtercondition เป็นALL "

หากไม่มียุคระบุไว้ในข้อมูลเข้าดังนั้นหนังสือเล่มนี้จะถือว่าครอบคลุมทุกยุคทุกสมัย

ฉันจะทำให้มันกลับหัว: หนังสือเล่มนี้ไม่ครอบคลุมถึงยุคสมัยที่เฉพาะเจาะจง

สิ่งนี้ยังสอดคล้องจากมุมมองของแบบสอบถาม:

หากไม่มีการเลือกยุคหนังสือทั้งหมดจะถูกส่งคืน (รวมถึงสิ่งนี้ด้วยฟิลด์ยุคว่าง) และเมื่อเลือกยุคแล้วจะมีการส่งคืนเฉพาะหนังสือที่มียุคที่เลือกเท่านั้น - การเรียกคืนหนังสือทุกเล่มจากยุคพิเศษ

จุดเดียวที่ฉันจะเพิ่มALL- หมวดหมู่มีไว้เพื่อความสะดวกของผู้ใช้เพราะอาจจะน่ารำคาญกว่าถ้าเลือก "ไม่มี" แทนที่จะเป็น "ทุกอย่าง"


0

ฉันเพิ่งใช้งานตัวกำหนดตารางเวลาพื้นฐานเมื่อเร็ว ๆ นี้และเนื่องจาก @LoztInSpace พูดถึงแล้วส่วนใหญ่เป็น UI น้ำตาล

อินเทอร์เฟซผู้ใช้จะต้องชัดเจนในสิ่งที่ผู้ใช้จะบรรลุเมื่อเลือกหนึ่งในตัวเลือก

ในกรณีของฉันฉันมีวันธรรมดาให้เลือก นอกจากตัวเลือก "ทั้งหมด" ฉันเพิ่ม "วันทำงาน" และ "วันหยุด" การเลือกแต่ละตัวเลือกจะรวมไว้ในการใช้งานในภายหลังและคุณจะต้องยกเลิกการเลือกวันที่คุณไม่ต้องการรวมด้วยตนเอง

ในทางเทคนิคหมายความว่าหากผู้ใช้เลือก "วันธรรมดา" UI จะมีช่องทำเครื่องหมายห้าช่องและเครื่องหมาย enum จะใช้ค่า "วันทำงาน" หากหนึ่งในช่องทำเครื่องหมายไม่ถูกล้างค่า "วันทำงาน" จะถูกแทนที่ด้วยแผนที่บิตหรือส่วนที่เหลืออีกสี่วัน

อย่าใช้ส่วนหนึ่งของตัวเลือกเพื่อรวมทุกอย่างและในเวลาเดียวกันเพื่อแยกบางสิ่งบางอย่างเพื่อหลีกเลี่ยงความขัดแย้งและตรวจสอบให้แน่ใจว่า UI เหมาะสมกับผู้ใช้

ฉันคิดว่าการวางแนวที่ดีคือการใช้และตัวเลือก "ทั้งหมด" สมเหตุสมผลถ้าผู้ใช้สามารถเข้าใจแนวคิดว่า "ทั้งหมด" รวมถึง (ทุกวันในหนึ่งสัปดาห์) หรือหากค่อนข้างไม่สำคัญ (ค้นหาทุกประเภทในอเมซอน)


0

ฉันชอบความคิดที่จะพก ALL enum อย่างชัดเจน แต่ฉันอยากให้พวกเขาเป็นธง

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

การใช้ไลบรารี่หรือเล่นด้วยตนเองด้วยการทำงานระดับบิตเมื่อเลือกค่าทั้งหมดคุณจะใช้ ALL แทน

โปรดทราบว่าค่าของ enum ควรเป็นสองเท่าของรุ่นก่อนเสมอ และสำหรับการตรวจสอบสติคุณไม่ควรลบ enum ถึงแม้ว่าคุณอาจปิดการใช้งานมันปรับรหัสของคุณเพื่อนับคนที่ถูกปิดการใช้งานเป็นส่วนหนึ่งของทั้งหมด

แม้ว่าฉันจะมีการตั้งค่าสถานะ NONE แทนและให้ลูกค้าตัดสินใจว่าจะทำอย่างไรเมื่อใช้ NONE ในกรณีที่ธุรกิจมีการเปลี่ยนแปลงในภายหลัง

หากการใช้งานนี้เกิดขึ้นแทนที่จะส่งผ่านไปรอบ ๆ คุณจะผ่านผลรวมของค่าที่เลือกแทน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.