0Pricing
Swift Academy · درس

لماذا نستخدم حقن التبعيات

افصل الإنشاء عن الاستخدام لتحسين قابلية الاختبار.

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

لماذا حقن الاعتماديات

يعني حقن الاعتماديات تزويد الكائن بما يحتاج إليه من الخارج بدلًا من أن ينشئه بنفسه. يؤدي ذلك إلى فصل المكوّنات ويجعل اختبارها أسهل.

المشكلة: الاقتران الشديد

عندما ينشئ نوعٌ ما المكوّنات المتعاونة معه بنفسه، يصبح مرتبطًا بتلك الفئات الملموسة ولا يمكن إعادة تهيئته أو اختباره بمعزل عن غيره.

class Logger {
    func log(_ m: String) { print("LOG: \(m)") }
}
class Service {
    let logger = Logger() // hard-coded dependency
    func run() { logger.log("running") }
}
Service().run()

الاقتران يعيق الاختبار

بما أن Service ينشئ دائمًا Logger حقيقيًا، فلا يستطيع الاختبار التقاط مخرجات السجل أو محاكاتها. وتصبح الاعتمادية مخفية عن الخارج.

class Logger { func log(_ m: String) { print(m) } }
class Service {
    let logger = Logger()
    func run() { logger.log("hello") }
}
// No way to swap Logger here.
Service().run()

الفكرة: احقنه

بدلًا من ذلك، مرّر الاعتمادية إلى الكائن. يحدد المستدعي التنفيذ الذي سيوفره، ولذلك لا يعود Service مهتمًا بالتفاصيل.

class Logger { func log(_ m: String) { print("LOG: \(m)") } }
class Service {
    let logger: Logger
    init(logger: Logger) { self.logger = logger }
    func run() { logger.log("running") }
}
Service(logger: Logger()).run()

فوائد الفصل

باستخدام الحقن، يعمل Service نفسه مع مسجلات مختلفة، في بيئة الإنتاج أو الاختبارات، من دون تغيير شفرته.

class Logger { var lines: [String] = []
    func log(_ m: String) { lines.append(m) } }
class Service {
    let logger: Logger
    init(logger: Logger) { self.logger = logger }
    func run() { logger.log("event") }
}
let l = Logger()
Service(logger: l).run()
print(l.lines)

المسؤولية الواحدة

يدعم حقن الاعتماديات مبدأ المسؤولية الواحدة: يركّز النوع على مهمته ويفوّض الاهتمامات الأخرى إلى المكوّنات المتعاونة المحقونة.

struct Mailer { func send(_ to: String) { print("Mail to \(to)") } }
struct SignupFlow {
    let mailer: Mailer
    func register(_ email: String) { mailer.send(email) }
}
SignupFlow(mailer: Mailer()).register("a@b.com")

المرونة

يمكنك إعادة تركيب الكائنات بطرق جديدة. يحدث توصيل المكوّنات عند أطراف التطبيق، مما يحافظ على مرونة النواة.

struct Engine { let power: Int }
struct Car {
    let engine: Engine
    func describe() { print("Power: \(engine.power)") }
}
Car(engine: Engine(power: 200)).describe()
Car(engine: Engine(power: 90)).describe()

الاعتماديات الصريحة

يوثّق المُهيّئ الذي يسرد اعتمادياته ما يحتاج إليه النوع بالضبط. أما الاعتماديات المخفية التي ينشئها النوع بنفسه فتحجب هذا العقد.

struct Repo { func load() -> [Int] { [1, 2, 3] } }
struct Report {
    let repo: Repo // visible dependency
    func total() -> Int { repo.load().reduce(0, +) }
}
print(Report(repo: Repo()).total())

التركيب بدلًا من الإنشاء

يفضّل حقن الاعتماديات تركيب الكائنات من الخارج. إذ يجمع جذر تركيب صغير الرسم البياني، بينما يتلقى بقية الشفرة ما تحتاج إليه فحسب.

struct DB { func count() -> Int { 42 } }
struct Stats { let db: DB; func show() { print(db.count()) } }
// Composition root:
let app = Stats(db: DB())
app.show()

ليس للتطبيقات الكبيرة فقط

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

struct Clock { func now() -> Int { 12 } }
struct Greeter {
    let clock: Clock
    func greet() { print(clock.now() < 12 ? "Morning" : "Afternoon") }
}
Greeter(clock: Clock()).greet()

لا حاجة إلى إطار عمل

لا يحتاج حقن الاعتماديات في Swift إلى مكتبة. تكفي المُهيّئات العادية والبروتوكولات. وستوضح الدروس القادمة حقن المُنشئ والبروتوكولات والمحاكاة.

struct Adder { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct Calc {
    let adder: Adder
    func run() { print(adder.add(2, 3)) }
}
Calc(adder: Adder()).run()

تحقق سريع

ما الفكرة الأساسية لحقن الاعتماديات؟

مراجعة

يوفّر حقن الاعتماديات المكوّنات المتعاونة من الخارج بدلًا من إنشائها داخليًا، مما يقلل الاقتران ويوضح الاعتماديات ويمكّن من الاختبار. ولا يحتاج إلى إطار عمل في Swift. سترى بعد ذلك الشكل الأكثر شيوعًا: حقن المُنشئ.

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

هل درس «لماذا نستخدم حقن التبعيات» مجاني؟

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

ماذا ستتعلم في «لماذا نستخدم حقن التبعيات»؟

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

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

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

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

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

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

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

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

  1. لماذا نستخدم حقن التبعيات
  2. حقن التبعيات عبر المُنشئ
  3. التجريدات المستندة إلى البروتوكولات
  4. محاكاة التبعيات في الاختبارات
← العودة إلى Swift Academy