Java EnumSet.range: สร้างช่วงสถานะแบบ type-safe และประหยัด
ถ้า enum เรียงเป็นขั้นตอนจริง เช่น ระดับการตรวจจาก REVIEW ถึง RELEASED เราอาจต้องสร้าง set ที่รวมค่าระหว่างสองขอบ EnumSet.range(from, to) ทำให้ได้ชุด type-safe รวมทั้งหัวและท้าย โดย implementation ใช้ bit vector ที่กะทัดรัด
import java.util.EnumSet;
public class Main {
enum Stage { DRAFT, REVIEW, VERIFIED, RELEASED, ARCHIVED }
static EnumSet<Stage> publishFlow() {
return EnumSet.range(Stage.REVIEW, Stage.RELEASED);
}
public static void main(String[] args) {
var stages = publishFlow();
assert stages.equals(EnumSet.of(
Stage.REVIEW, Stage.VERIFIED, Stage.RELEASED));
assert !stages.contains(Stage.DRAFT);
assert !stages.contains(Stage.ARCHIVED);
System.out.println(stages);
}
}
ภาพจำคือหยิบแฟ้มทุกใบระหว่างที่คั่นสองอัน ตามลำดับประกาศ enum ไม่ใช่ตาม label หรือค่าธุรกิจที่คำนวณภายนอก ดังนั้นการย้ายตำแหน่งสมาชิกภายหลังเปลี่ยนผลของ range แม้โค้ด caller ไม่เปลี่ยน
ใช้วิธีนี้เมื่อ order เป็นส่วนหนึ่งของโมเดลและมี test ป้องกัน หากสมาชิกเป็นหมวดที่บังเอิญเรียงติดกัน ควรใช้ EnumSet.of(...) เพื่อบอกชุดที่ต้องการตรง ๆ และลด coupling กับ ordinal from ต้องมาก่อนหรือเท่ากับ to; ถ้ากลับด้านจะได้ exception ไม่ใช่ empty set
Recap
- ใช้เฉพาะ enum ที่ลำดับประกาศมีความหมายถาวร
- จำว่า range รวมทั้ง from และ to
- ใช้
ofเมื่อสมาชิกไม่ใช่ช่วงโดเมนจริง - เพิ่ม regression test ก่อนจัดลำดับ enum ใหม่