مقدمة إلى أنماط التصميم في Kotlin
أنماط التصميم (design patterns) هي حلول مجربة للمشاكل النمطية في التطوير. في لغة Kotlin، يتم تنفيذ العديد من الأنماط الكلاسيكية بشكل أكثر إيجازاً وأماناً بفضل الإمكانيات المدمجة: الأمان من القيم الفارغة (null-safety)، دوال التوسيع (extension functions)، الكوروتينات (coroutines)، ونظام الأنواع القوي.
في هذه المقالة، سنشرح ثلاث مجموعات من الأنماط: الإنشائية (creational)، الهيكلية (structural)، والسلوكية (behavioral) - مع أمثلة عملية بلغة Kotlin. ستتعلم كيفية استخدامها في التطوير اليومي لبناء بنية مرنة وقابلة للصيانة.
الأنماط الإنشائية (Creational)
1. Singleton (المفرد)
في Kotlin، يتم تنفيذ النمط المفرد باستخدام الكلمة المفتاحية object. هذا يضمن مفرداً آمنًا للخيوط (thread-safe) وكسولاً (lazy) بدون كود زائد.
object DatabaseConnection { private val url = "jdbc:postgresql://localhost:5432/mydb" private val user = "admin" private val password = "secret"
fun connect(): String { return "Connected to $url as $user" }}
fun main() { println(DatabaseConnection.connect()) // نتحقق من أنه نفس الكائن val ref1 = DatabaseConnection val ref2 = DatabaseConnection println(ref1 === ref2) // true}الميزة: لا حاجة لكتابة synchronized أو volatile - Kotlin يضمن وجود مثيل واحد فقط.
2. Factory Method (طريقة المصنع)
يسمح بتفويض إنشاء الكائنات إلى الفئات الفرعية. في Kotlin، من المناسب استخدام sealed class و companion object.
sealed class Notification { data class Email(val to: String, val subject: String) : Notification() data class SMS(val phone: String, val message: String) : Notification() data class Push(val deviceId: String, val title: String) : Notification()
companion object Factory { fun createEmail(to: String, subject: String): Notification = Email(to, subject) fun createSMS(phone: String, message: String): Notification = SMS(phone, message) fun createPush(deviceId: String, title: String): Notification = Push(deviceId, title) }}
fun send(notification: Notification) { when (notification) { is Notification.Email -> println("Email to ${notification.to}") is Notification.SMS -> println("SMS to ${notification.phone}") is Notification.Push -> println("Push to ${notification.deviceId}") }}
fun main() { val email = Notification.createEmail("user@example.com", "Hello") send(email)}3. Builder (الباني)
في Kotlin، يمكن استبدال Builder بالوسائط المسماة (named arguments) والقيم الافتراضية. لكن بالنسبة للكائنات المعقدة التي تحتاج إلى تحقق (validation)، يبقى Builder الكلاسيكي مناسباً.
class Pizza private constructor( val size: String, val cheese: Boolean, val pepperoni: Boolean, val mushrooms: Boolean) { class Builder { private var size: String = "Medium" private var cheese: Boolean = false private var pepperoni: Boolean = false private var mushrooms: Boolean = false
fun size(size: String) = apply { this.size = size } fun cheese() = apply { this.cheese = true } fun pepperoni() = apply { this.pepperoni = true } fun mushrooms() = apply { this.mushrooms = true }
fun build(): Pizza { require(size in listOf("Small", "Medium", "Large")) { "Invalid size" } return Pizza(size, cheese, pepperoni, mushrooms) } }}
fun main() { val pizza = Pizza.Builder() .size("Large") .cheese() .pepperoni() .build() println("Pizza: ${pizza.size}, cheese=${pizza.cheese}, pepperoni=${pizza.pepperoni}")}الأنماط الهيكلية (Structural)
4. Adapter (المهايئ)
المهايئ يسمح للكائنات ذات ال