أنماط حالات الاستخدام والمستودع
عرّفوا حالات الاستخدام كبروتوكولات Swift ونفّذوا واجهات المستودعات.
أنماط حالات الاستخدام والمستودع درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.
ما حالة الاستخدام؟
تغلف حالة الاستخدام (interactor) إجراءً تجاريًا واحدًا، وتنسّق بين كيانات المجال والمستودعات.
struct PlaceOrderUseCase {
let cart: CartRepository
let payment: PaymentService
let orders: OrderRepository
func execute(userId: Int) async throws -> Order {
let items = try await cart.items(for: userId)
let receipt = try await payment.charge(items: items)
return try await orders.create(receipt: receipt)
}
}المسؤولية الواحدة
تنفذ كل حالة استخدام مهمة واحدة فقط. وتعني المسؤوليات المتعددة وجود حالات استخدام متعددة.
// One use case per business action:
struct FetchUserUseCase { ... }
struct UpdateUserUseCase { ... }
struct DeleteUserUseCase { ... }حالة الاستخدام كبروتوكول
عرّف بروتوكولًا لحالة الاستخدام حتى تتمكن من محاكاتها في اختبارات طبقة العرض.
protocol PlacingOrder {
func execute(userId: Int) async throws -> Order
}
struct PlaceOrderUseCase: PlacingOrder { ... }ما المستودع؟
يجرد المستودع مصدر البيانات. ويتفاعل المستدعون مع بروتوكول Swift، بينما قد يكون التطبيق قائمًا على الشبكة أو Core Data أو الذاكرة.
protocol OrderRepository {
func create(receipt: PaymentReceipt) async throws -> Order
func list(userId: Int) async throws -> [Order]
func cancel(orderId: Int) async throws
}تطبيق المستودع
يحوّل المستودع الملموس استدعاءات المجال إلى عمليات على الشبكة أو قاعدة البيانات.
struct RemoteOrderRepository: OrderRepository {
func create(receipt: PaymentReceipt) async throws -> Order {
let dto = receipt.toDTO()
let data = try await api.post("/orders", body: dto)
return try JSONDecoder().decode(OrderDTO.self, from: data).toDomain()
}
func list(userId: Int) async throws -> [Order] { ... }
func cancel(orderId: Int) async throws { ... }
}مستودع داخل الذاكرة للاختبارات
وفر مستودعًا داخل الذاكرة لإجراء اختبارات سريعة وحتمية من دون عمليات إدخال وإخراج.
final class InMemoryOrderRepo: OrderRepository {
var orders: [Order] = []
func create(receipt: PaymentReceipt) async throws -> Order {
let order = Order(id: orders.count + 1, items: receipt.items)
orders.append(order)
return order
}
func list(userId: Int) async throws -> [Order] { orders }
func cancel(orderId: Int) async throws { orders.removeAll { $0.id == orderId } }
}تركيب حالات الاستخدام
يمكن لحالات الاستخدام استدعاء حالات استخدام أخرى لتنفيذ عمليات فرعية مشتركة، مع الحفاظ على تركيز كل حالة.
struct CheckoutUseCase {
let validateCart: ValidateCartUseCase
let placeOrder: PlaceOrderUseCase
let notifyUser: NotifyUserUseCase
func execute(userId: Int) async throws -> Order {
try await validateCart.execute(userId: userId)
let order = try await placeOrder.execute(userId: userId)
try await notifyUser.execute(order: order)
return order
}
}المستودع مقابل الخدمة
المستودع: ينفذ عمليات CRUD على نوع كيان واحد. الخدمة: تنسّق بين كيانات متعددة أو تستدعي واجهات برمجة تطبيقات خارجية من دون تخزين مباشر.
// Repository: single entity
protocol UserRepository { func getUser(id: Int) async throws -> User }
// Service: cross-entity operation
protocol AuthService { func login(email: String, password: String) async throws -> Session }التخزين المؤقت في المستودعات
يمكن للمستودعات تخزين النتائج مؤقتًا بشفافية، من دون أن تعرف حالة الاستخدام تفاصيل التطبيق.
struct CachedUserRepository: UserRepository {
private var cache: [Int: User] = [:]
private let remote: UserRepository
func getUser(id: Int) async throws -> User {
if let cached = cache[id] { return cached }
let user = try await remote.getUser(id: id)
cache[id] = user
return user
}
func saveUser(_ user: User) async throws { try await remote.saveUser(user) }
}قابلية الاختبار
بما أن حالات الاستخدام تعتمد على مستودعات معرفة بالبروتوكولات، يمكنك حقن بدائل لاختبار منطق الأعمال بمعزل عن بقية النظام.
let repo = InMemoryOrderRepo()
let sut = PlaceOrderUseCase(orders: repo, ...)
let order = try await sut.execute(userId: 1)
XCTAssertEqual(repo.orders.count, 1)ترجمة الأخطاء
ينبغي للمستودعات ترجمة أخطاء طبقة البيانات (الشبكة وقاعدة البيانات) إلى أخطاء المجال قبل إرجاعها.
func getUser(id: Int) async throws -> User {
do {
let data = try await api.get("/users/\(id)")
return try decode(data)
} catch let e as URLError where e.code == .notConnectedToInternet {
throw DomainError.offline
}
}تحقق سريع
ما الفرق الأساسي بين المستودع والخدمة في البنية المعمارية النظيفة؟
مراجعة الدرس
تغلف حالات الاستخدام إجراءات تجارية واحدة وتعتمد على بروتوكولات المستودعات. وتُجرد المستودعات مصادر البيانات خلف بروتوكول. استخدم مستودعات داخل الذاكرة لإجراء اختبارات سريعة. وتترجم المستودعات أخطاء البنية التحتية إلى أخطاء المجال. أما الخدمات فتنسّق العمليات التي تشمل كيانات متعددة.
تعلم Swift مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 122
- الدروس
- 409
الأسئلة الشائعة
هل درس «أنماط حالات الاستخدام والمستودع» مجاني؟
نعم — نص درس «أنماط حالات الاستخدام والمستودع» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.
ماذا ستتعلم في «أنماط حالات الاستخدام والمستودع»؟
عرّفوا حالات الاستخدام كبروتوكولات Swift ونفّذوا واجهات المستودعات. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟
لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «أنماط حالات الاستخدام والمستودع»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟
نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الطبقات: النطاق والبيانات والعرض
- أنماط حالات الاستخدام والمستودع
- عكس التبعيات باستخدام تجريدات البروتوكولات
- وصل الطبقات معًا دون إطار DI