أنماط التصميم في Swift: من الأساسيات إلى التطبيق العملي
أنماط التصميم (Design Patterns) هي حلول مجربة للمشكلات النمطية في التطوير. في عالم Swift ونظام Apple البيئي (iOS/macOS)، تصبح معرفتها إلزامية لإنشاء كود قابل للصيانة والاختبار والتوسع. في هذه المقالة، سنحلل الأنماط الرئيسية، مقسمين إياها إلى ثلاث فئات رئيسية: الإنشائية والهيكلية والسلوكية. سيتم توضيح كل نمط بمثال عملي بلغة Swift.
الأنماط الإنشائية: Singleton و Factory Method و Builder
الأنماط الإنشائية مسؤولة عن عملية إنشاء الكائنات، مما يجعلها أكثر مرونة واستقلالية عن كود العميل.
Singleton (المفرد)
يضمن وجود مثيل واحد فقط للفئة، ويوفر نقطة وصول عالمية إليه. في iOS، يُستخدم غالبًا لإدارة جلسات الشبكة، قواعد البيانات (Core Data)، أو إعدادات التطبيق.
class NetworkManager { static let shared = NetworkManager() private init() {} func fetchData(from url: URL) { // منطق الطلب print("Fetching data from \\(url)") }}
// الاستخدامNetworkManager.shared.fetchData(from: URL(string: "https://example.com")!)Factory Method (طريقة المصنع)
يحدد واجهة لإنشاء كائن، لكنه يسمح للفئات الفرعية بتغيير نوع الكائن الذي يتم إنشاؤه. مناسب تمامًا لإنشاء مكونات واجهة المستخدم حسب إصدار iOS أو التكوين.
protocol Button { func render()}
class iOSButton: Button { func render() { print("Rendering iOS button") }}
class macOSButton: Button { func render() { print("Rendering macOS button") }}
enum Platform { case iOS, macOS }
class ButtonFactory { static func createButton(for platform: Platform) -> Button { switch platform { case .iOS: return iOSButton() case .macOS: return macOSButton() } }}
// الاستخدامlet button = ButtonFactory.createButton(for: .iOS)button.render()Builder (الباني)
يسمح بإنشاء كائنات معقدة خطوة بخطوة. يُستخدم على نطاق واسع لتكوين الطلبات (URLRequest) أو إعدادات واجهة المستخدم المعقدة.
class Pizza { var dough: String = "" var cheese: String = "" var toppings: [String] = []}
class PizzaBuilder { private var pizza = Pizza() func setDough(_ dough: String) -> PizzaBuilder { pizza.dough = dough return self } func setCheese(_ cheese: String) -> PizzaBuilder { pizza.cheese = cheese return self } func addTopping(_ topping: String) -> PizzaBuilder { pizza.toppings.append(topping) return self } func build() -> Pizza { return pizza }}
// الاستخدامlet margherita = PizzaBuilder() .setDough("Thin") .setCheese("Mozzarella") .addTopping("Basil") .build()الأنماط الهيكلية: Adapter و Decorator و Facade
الأنماط الهيكلية تبسط التصميم من خلال تحديد طرق دمج الكائنات والفئات في هياكل أكبر.
Adapter (المهايئ)
يسمح للكائنات ذات الواجهات غير المتوافقة بالعمل معًا. مثال كلاسيكي هو دمج المكتبات الخارجية أو العمل مع كود قديم.
// البروتوكول القديمprotocol OldPaymentSystem { func pay(amount: Double)}
// البروتوكول الجديدprotocol NewPaymentSystem { func processPayment(amount: Double, currency: String)}
// المهايئclass PaymentAdapter: NewPaymentSystem { private let oldSystem: OldPaymentSystem init(oldSystem: OldPaymentSystem) { self.oldSystem = oldSystem } func processPayment(amount: Double, currency: String) { // تحويل العملة let convertedAmount = amount * 1.1 oldSy