นากต้นฉบับเลือกแผ่นสถานะที่เรียงติดกันระหว่างหมุดสองจุดบนฉากสว่าง

Java EnumSet.range: สร้างช่วงสถานะแบบ type-safe และประหยัด

พี่โชว์Engineering

ถ้า 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 ใหม่