0Pricing
Kotlin Academy · درس

نمذجة المجالات الوظيفية باستخدام الأنواع الأساسية في Arrow

نمذج المجالات المعقدة باستخدام Either وNonEmptyList وتجميع الأخطاء بعد التحقق

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

ما نمذجة المجال الوظيفية؟

تستخدم نمذجة المجال الوظيفية الأنواع الجبرية مثل (Either وOption والأصناف المختومة) لترميز قواعد العمل داخل الأنواع. تصبح الحالات غير الصالحة غير قابلة للتمثيل وقت الترجمة، وتكون الأخطاء صريحة في تواقيع الدوال، من دون استثناءات مخفية.

كائنات القيم باستخدام Inline/Value Classes

استخدم value classes في Kotlin لتغليف الأنواع البدائية ومنع هوس الأنواع البدائية. يرفض نظام الأنواع تمرير UserId عندما يكون المتوقع هو PostId:

@JvmInline value class UserId(val value: Long)
@JvmInline value class PostId(val value: Long)

fun findUser(id: UserId): Either<UserError, User> = TODO()
// findUser(PostId(1L))  // Compile error!

الأصناف المختومة لأخطاء المجال

نمذج الأخطاء على هيئة تسلسلات من الأصناف المختومة. تحمل كل فئة فرعية البيانات ذات الصلة بحالة الخطأ تلك فقط:

sealed class UserError {
    data class NotFound(val id: UserId) : UserError()
    data class EmailTaken(val email: String) : UserError()
    data class ValidationFailed(val field: String, val reason: String) : UserError()
}

Validated: تجميع أخطاء متعددة

عندما تريد الإبلاغ عن جميع أخطاء التحقق دفعة واحدة، وليس عن الخطأ الأول فقط، استخدم Validated في Arrow، أو zipOrAccumulate في Raise DSL. فهو يجمع الأخطاء داخل NonEmptyList:

import arrow.core.Validated
import arrow.core.valid
import arrow.core.invalid

fun validateName(name: String): Validated<String, String> =
    if (name.isNotBlank()) name.valid() else "Name is blank".invalid()

تركيب عمليات التحقق

استخدم zip() لدمج نتائج Validated متعددة. إذا كانت أي نتيجة منها Invalid، فسيتم تجميع جميع الأخطاء:

val result: Validated<NonEmptyList<String>, User> =
    validateName(name).zip(validateEmail(email)) { n, e -> User(n, e) }
        .mapLeft { it }

جعل الحالات غير القانونية غير قابلة للتمثيل

بدلاً من استخدام User يحتوي على email قابلاً لـ null وعلامة isVerified، استخدم أصنافاً فرعية مختومة بحيث يمنع نظام الأنواع الوصول إلى email لمستخدم لم يتم التحقق منه:

sealed class User {
    data class Unverified(val id: UserId, val pendingEmail: String) : User()
    data class Verified(val id: UserId, val email: String) : User()
}

المنشئات الذكية

استخدم دوال مصنع في companion object تُرجع Either أو Option بدلاً من المنشئات العامة. يضمن ذلك أن تكون المثيلات دائماً في حالة صالحة:

class Email private constructor(val value: String) {
    companion object {
        fun of(raw: String): Either<String, Email> =
            if (raw.contains("@") && raw.length <= 255) Email(raw).right()
            else "Invalid email format".left()
    }
}

دمج Either وOption في مسار واحد

عادةً ما تجمع عملية حقيقية في المجال بين عمليات البحث في المستودعات (Option) وعمليات التحقق (Either). استخدم كتلة Arrow‏ either { } مع .bind() لتركيبهما بسلاسة:

fun createPost(authorId: UserId, title: String, body: String): Either<PostError, Post> = either {
    val author = userRepo.findById(authorId).toEither { PostError.AuthorNotFound }.bind()
    val validTitle = validateTitle(title).bind()
    postRepo.save(Post(author, validTitle, body))
}

عدم القابلية للتغيير وCopy

ينبغي أن تكون كيانات المجال غير قابلة للتغيير. استخدم فئات البيانات وcopy() لاشتقاق حالات جديدة. تتيح Lens في Arrow، من arrow-optics، تحديثات متداخلة سهلة الاستخدام من دون تعديل مباشر:

val updated = user.copy(email = "new@example.com")
// Arrow Optics:
val emailLens = User.email
val updatedWithLens = emailLens.set(user, "new@example.com")

إعداد آمن للأنواع باستخدام الأصناف المختومة

نمذج متغيرات إعدادات التطبيق باستخدام أصناف مختومة، بحيث يجبرك المترجم على معالجة كل حالة:

sealed class DbConfig {
    data class Postgres(val url: String, val user: String, val pass: String) : DbConfig()
    data class InMemory(val dbName: String = "test") : DbConfig()
}

الفوائد بإيجاز

توفر نمذجة المجال الوظيفية باستخدام الأنواع الأساسية في Arrow ما يلي:

  • عدم حدوث استثناءات مؤشرات null في شفرات المجال
  • ظهور الأخطاء في تواقيع الدوال
  • تحققات شاملة باستخدام when على التسلسلات الهرمية المختومة
  • دوال نقية قابلة للاختبار
  • شفرات تشرح نفسها

اختبار سريع

ما الفائدة الأساسية من استخدام تسلسل هرمي من sealed class لأخطاء المجال بدلاً من إطلاق الاستثناءات؟

مراجعة: نمذجة المجال الوظيفية باستخدام الأنواع الأساسية في Arrow

أهم النقاط:

  • تمنع value classes هوس الأنواع البدائية
  • تجعل التسلسلات الهرمية للأخطاء حالات الفشل شاملة وآمنة من ناحية الأنواع
  • تضمن المنشئات الذكية إنشاء مثيلات صالحة
  • تتيح either { }.bind() تركيب العمليات القابلة للفشل بطريقة واضحة
  • توفر البيانات غير القابلة للتغيير مع copy() أو Arrow Optics انتقالات آمنة بين الحالات

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

هل درس «نمذجة المجالات الوظيفية باستخدام الأنواع الأساسية في Arrow» مجاني؟

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

ماذا ستتعلم في «نمذجة المجالات الوظيفية باستخدام الأنواع الأساسية في Arrow»؟

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

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

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

كم من الوقت يستغرق درس «نمذجة المجالات الوظيفية باستخدام الأنواع الأساسية في Arrow»؟

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

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

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

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

  1. ‏Either : معالجة الأخطاء ذات الأنواع من دون استثناءات
  2. Arrow Raise DSL: تركيب الأخطاء المعرّفة بالأنواع
  3. Option وNullable: متى تستخدم كلًّا منهما
  4. نمذجة المجالات الوظيفية باستخدام الأنواع الأساسية في Arrow
← العودة إلى Kotlin Academy