0Pricing
TypeScript Academy · درس

نمذجة المجال — التجميعات والثوابت والخدمات

نمذج تجميعات مثل Cart باستخدام معرّفات موسومة، وطبّق الثوابت عبر المصانع والخدمات.

نمذجة المجال — التجميعات والثوابت والخدمات درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

مقدمة

الهدف: نمذجة aggregate باسم Cart باستخدام المعرّفات الموسومة وضمان فرض قواعد مثل qty > 0 في المصانع والخدمات.

  • تميّز المعرّفات الموسومة حدود الكيانات
  • تُرجع المصانع اتحاد Result
  • تتجنب دوال الخدمة الانتقالات غير الصالحة

الكيانات والأوسمة

تجعل المعرّفات الموسومة 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

التجميع والثابت

تتحقق المصانع من القواعد: يجب أن تكون qty أكبر من > 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" }

تعيين الحدود

عند الحدود (مثل واجهات API)، حوّلوا البيانات إلى DTOs وتحققوا منها عند تحليلها مجددًا. وتضمن المصانع صحة البيانات.

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) } }
}

نصائح

أفضل الممارسات:

  • مركزة التحقق في المصانع.
  • الحفاظ على دوال الخدمة نقية وحتمية.
  • إجراء تحويلات الأوسمة عند حدود النظام فقط.

التحقق من الثابت

تحقق سريع: كيف ينبغي فرض ثابت مثل qty > 0؟

مراجعة

مراجعة: تفرض المعرّفات الموسومة، مع المصانع والخدمات، الثوابت. ولا يمكن إنشاء حالات غير صالحة لأن جميع نقاط الدخول تتحقق من المدخلات.

الأسئلة الشائعة

هل درس «نمذجة المجال — التجميعات والثوابت والخدمات» مجاني؟

نعم — نص درس «نمذجة المجال — التجميعات والثوابت والخدمات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

ماذا ستتعلم في «نمذجة المجال — التجميعات والثوابت والخدمات»؟

نمذج تجميعات مثل Cart باستخدام معرّفات موسومة، وطبّق الثوابت عبر المصانع والخدمات. تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.

كم من الوقت يستغرق درس «نمذجة المجال — التجميعات والثوابت والخدمات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الأنواع الموسومة لمنع الخلط بين الوحدات
  2. المعرّفات الموسومة وأنماط نمذجة المجال
  3. نمذجة المجال — التجميعات والثوابت والخدمات
← العودة إلى TypeScript Academy