إنشاء DSL آمن للأنواع لـ HTML/Config
نفّذ DSL بسيطًا للإعدادات باستخدام أنماط البناء وامتدادات lambda.
إنشاء DSL آمن للأنواع لـ HTML/Config درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
الهدف: إنشاء DSL عملية
سنبني DSL بسيطة لكنها واقعية لإنشاء HTML في Kotlin. وتنطبق الأنماط نفسها على أي منشئ إعدادات أو تركيبات اختبار أو تقارير. والنتيجة هي واجهة برمجة تطبيقات آمنة النوع وملائمة لبيئة التطوير المتكاملة، تستبدل دمج السلاسل النصية.
تعريف الفئة الأساسية للوسم
تشترك جميع عناصر HTML في البنية نفسها: اسم وسمات وعناصر فرعية. ابدأ بفئة أساسية:
open class Tag(val name: String) {
val attrs = mutableMapOf<String, String>()
val children = mutableListOf<Tag>()
fun render(indent: Int = 0): String {
val pad = " ".repeat(indent)
val attrStr = if (attrs.isEmpty()) "" else " " + attrs.entries.joinToString(" ") { "${it.key}=\"${it.value}\"" }
val body = children.joinToString("\n") { it.render(indent + 2) }
return "$pad<$name$attrStr>\n$body\n$pad</$name>"
}
}تطبيق @DslMarker
علّم جميع فئات البناء حتى لا تتمكن النطاقات الداخلية من استدعاء دوال النطاق الخارجي عرضًا:
@DslMarker
annotation class HtmlDsl
@HtmlDsl class Html : Tag("html")
@HtmlDsl class Head : Tag("head")
@HtmlDsl class Body : Tag("body")
@HtmlDsl class Div : Tag("div")
@HtmlDsl class P : Tag("p")إضافة دوال البناء
تحصل كل فئة وسم على دالة امتداد تنشئ وسمًا فرعيًا، وتطبّق الكتلة، ثم تضيفه إلى العناصر الفرعية:
fun Html.head(block: Head.() -> Unit) = Head().also { it.block(); children += it }
fun Html.body(block: Body.() -> Unit) = Body().also { it.block(); children += it }
fun Body.div(block: Div.() -> Unit) = Div().also { it.block(); children += it }
fun Div.p(text: String) = P().also { it.attrs["text"] = text; children += it }دالة بناء html ذات المستوى الأعلى
وفّر نقطة دخول ذات مستوى أعلى تنشئ العنصر الجذر وتطبّق كتلة المستخدم:
fun html(block: Html.() -> Unit): Html {
val root = Html()
root.block()
return root
}استخدام DSL
تكون النتيجة DSL نظيفة وسهلة القراءة:
val page = html {
head { }
body {
div {
p("Hello, DSL!")
}
}
}
println(page.render())إضافة السمات
أضف دالة مساعدة attr لتعيين السمات العشوائية بطريقة انسيابية:
fun Tag.attr(key: String, value: String) { attrs[key] = value }
// Usage
div {
attr("class", "container")
p("Content")
}نمط DSL للإعدادات
يعمل النمط نفسه مع كائنات الإعدادات. فبدلًا من وسوم HTML، استخدم أصناف المجال:
class ServerConfig {
var host = "localhost"
var port = 8080
var db: DbConfig? = null
fun database(block: DbConfig.() -> Unit) { db = DbConfig().apply(block) }
}
fun server(block: ServerConfig.() -> Unit) = ServerConfig().apply(block)التداخل والتركيب
بما أن كل دالة بناء تعيد الكائن الذي أنشأته، يمكنك تركيب دوال البناء بحرية. ويتوافق عمق تداخل DSL مع عمق التسلسل الهرمي للبيانات.
منع الأخطاء باستخدام الأنواع
يفرض نظام الأنواع البنية المطلوبة: لا يمكنك استدعاء body { } داخل Head لأن Head لا تملك دالة امتداد body. وتصبح البنى غير الصالحة أخطاءً في وقت الترجمة.
التصيير والاختبار
بما أن DSL تنتج شجرة كائنات عادية في Kotlin، فإن التصيير والاختبار مباشران: استدعِ render() وتحقّق من سلسلة الناتج، أو تجوّل في شجرة الكائنات داخل الاختبارات.
توسعة DSL لاحقًا
لا تتطلب إضافة وسوم أو خيارات إعداد جديدة سوى إضافة دوال توسعة جديدة إلى صنف المستقبل المناسب. ولا تتأثر مواضع الاستدعاء الحالية — وهذا يحقق مبدأ الانفتاح والإغلاق عمليًا.
تحقق سريع
ما الذي يجعل DSL الخاص بـ Kotlin لإنشاء HTML أو الإعدادات «آمنًا من حيث الأنواع»؟
مراجعة: بناء DSL آمن من حيث الأنواع
الخطوات الأساسية:
- تعريف أصناف بنّاء لكل مستوى من مستويات التدرج الهرمي
- استخدام
@DslMarkerلمنع تسرّب المستقبلات - كتابة دوال توسعة تنشئ الكائنات التابعة وتضبطها وتضيفها
- إتاحة دالة نقطة دخول على مستوى الحزمة
- يعمل العرض والاختبار على كائنات Kotlin عادية
الأسئلة الشائعة
هل درس «إنشاء DSL آمن للأنواع لـ HTML/Config» مجاني؟
نعم — نص درس «إنشاء DSL آمن للأنواع لـ HTML/Config» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
ماذا ستتعلم في «إنشاء DSL آمن للأنواع لـ HTML/Config»؟
نفّذ DSL بسيطًا للإعدادات باستخدام أنماط البناء وامتدادات lambda. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟
لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «إنشاء DSL آمن للأنواع لـ HTML/Config»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟
نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- Lambda مع مستقبل: أساس DSL
- @DslMarker: منع تسرّب المستقبلات
- إنشاء DSL آمن للأنواع لـ HTML/Config
- اختبار DSL وتطويره من دون التأثير في المستخدمين