0Pricing
TypeScript Academy · บทเรียน

การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ

สร้างโมเดลกลุ่มรวม เช่น Cart ด้วยรหัสประจำตัวแบบมีแบรนด์ และบังคับใช้เงื่อนไขคงที่ผ่านโรงงานและบริการ

การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

บทนำ

เป้าหมาย: สร้างแบบจำลองแอกกริเกต Cart โดยใช้ID ที่มีแบรนด์ และทำให้แน่ใจว่ากฎอย่าง จำนวนสินค้า > 0 ถูกบังคับใช้ในฟังก์ชันโรงงานและบริการ

  • ID ที่มีแบรนด์ช่วยแยกขอบเขตของเอนทิตี
  • ฟังก์ชันโรงงานส่งกลับยูเนียนผลลัพธ์
  • ฟังก์ชันบริการหลีกเลี่ยงการเปลี่ยนสถานะที่ไม่ถูกต้อง

เอนทิตีและแบรนด์

ID ที่มีแบรนด์ทำให้ CartId และ ProductId ใช้แทนกันไม่ได้ แม้ว่าทั้งคู่จะเป็นสตริงก็ตาม จึงช่วยป้องกันการสลับค่าผิด

type Brand<Tag extends string, T> = T & { readonly __brand: Tag }

type CartId = Brand<"CartId", string>
type ProductId = Brand<"ProductId", string>

type Result<T> = { ok: true; value: T } | { ok: false; error: string }

const cartId = (s: string): CartId => s as CartId
const productId = (s: string): ProductId => s as ProductId

แอกกริเกตและเงื่อนไขคงที่

ฟังก์ชันโรงงานตรวจสอบกฎ: จำนวนต้องมากกว่า > 0 จึงจะสร้างอ็อบเจ็กต์ Line ที่ถูกต้องได้

type Money = number & { readonly __brand: "Money" }
const money = (n: number): Money => n as Money

interface Line { productId: ProductId; qty: number; price: Money }
interface Cart { id: CartId; lines: Line[]; total: Money }

function makeLine(productId: ProductId, qty: number, price: Money): Result<Line> {
  if (!Number.isInteger(qty) || qty <= 0) return { ok: false, error: "qty must be > 0" }
  return { ok: true, value: { productId, qty, price } }
}

function makeCart(id: CartId): Cart { return { id, lines: [], total: money(0) } }

บริการ: เพิ่มรายการ

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

function addItem(cart: Cart, line: Line): Result<Cart> {
  const lines = [...cart.lines, line]
  const totalNum = lines.reduce((s, x) => s + (x.qty * (x.price as number)), 0)
  if (!Number.isFinite(totalNum) || totalNum < 0) return { ok: false, error: "invalid total" }
  return { ok: true, value: { ...cart, lines, total: (totalNum as unknown) as Money } }
}

// Usage
const c0 = makeCart(cartId("c1"))
const l = makeLine(productId("p1"), 2, money(10))
const c1 = l.ok ? addItem(c0, l.value) : { ok: false, error: "bad line" }

การแมปที่ขอบเขต

ที่ขอบเขตของระบบ เช่น APIs ให้แปลงเป็นอ็อบเจ็กต์ถ่ายโอนข้อมูลและตรวจสอบเมื่อแปลงกลับ ฟังก์ชันโรงงานช่วยรับประกันว่าข้อมูลถูกต้อง

type CartDTO = { id: string; lines: { productId: string; qty: number; price: number }[]; total: number }

function serialize(c: Cart): CartDTO {
  return {
    id: c.id as unknown as string,
    lines: c.lines.map(x => ({ productId: x.productId as unknown as string, qty: x.qty, price: x.price as unknown as number })),
    total: c.total as unknown as number
  }
}

function parse(dto: CartDTO): Result<Cart> {
  const id = cartId(dto.id)
  const lines: Line[] = []
  for (const raw of dto.lines) {
    const l = makeLine(productId(raw.productId), raw.qty, money(raw.price))
    if (!l.ok) return { ok: false, error: l.error }
    lines.push(l.value)
  }
  const totalNum = lines.reduce((s, x) => s + (x.qty * (x.price as number)), 0)
  return { ok: true, value: { id, lines, total: money(totalNum) } }
}

เคล็ดลับ

แนวปฏิบัติที่ดี:

  • รวมศูนย์การตรวจสอบไว้ในฟังก์ชันโรงงาน
  • ทำให้ฟังก์ชันบริการบริสุทธิ์และให้ผลแน่นอน
  • แปลงแบรนด์เฉพาะที่ขอบเขตของระบบ

ตรวจสอบเงื่อนไขคงที่

ตรวจสอบอย่างรวดเร็ว: คุณควรบังคับใช้เงื่อนไขคงที่อย่าง จำนวน > 0 อย่างไร

ทบทวน

ทบทวน: ID ที่มีแบรนด์เมื่อใช้ร่วมกับฟังก์ชันโรงงานและบริการจะช่วยบังคับใช้เงื่อนไขคงที่ได้ สถานะที่ไม่ถูกต้องจะไม่สามารถสร้างขึ้นได้ เพราะทุกช่องทางเข้าตรวจสอบข้อมูลนำเข้า

คำถามที่พบบ่อย

บทเรียน “การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ”

สร้างโมเดลกลุ่มรวม เช่น Cart ด้วยรหัสประจำตัวแบบมีแบรนด์ และบังคับใช้เงื่อนไขคงที่ผ่านโรงงานและบริการ คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน

บทเรียน “การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ชนิดข้อมูลแบรนด์/ชนิดข้อมูลทึบเพื่อป้องกันการสับสนของหน่วย
  2. รหัสประจำตัวแบบติดป้ายกำกับและรูปแบบการสร้างโมเดนโดเมน
  3. การสร้างโมเดลโดเมน — กลุ่มรวม เงื่อนไขคงที่ และบริการ
← กลับไปที่ TypeScript Academy