در این مقاله برسی میکنیم که چگونه در سوئیفت یک object ناسازگار را به رابط هدف یا کلاس با استفاده از الگوی طراحی adapter تبدیل کنیم.
قبل از هرچیزی، به این مثال در دنیای واقعی که نمونه آن را که قرار است در سوئیفت بسازیم توجه کنید:
الگوی طراحی وفق دهنده یا Adapter یک الگوی طراحی ساختاری (creational) است که اجازه میدهد object هایی که رابط ناسازگار دارند با یکدیگر کار کنند. به عبارتی دیگر این الگو رابط یک object را تغییر میدهد تا با object های دیگر نیز کار کند.
پس adapter میتواند یک چیز را به چیز دیگر تبدیل کند و بعضی اوقات آن را بسته بندی کننده (wrapper) نیز می نامند زیرا object را بسته بندی میکند و یک رابط جدید برای آن ایجاد میکند. چیزی مانند یک دانگل نرم افزاری برای رابط های خاص و یا کلاس های قدیمی.
پیاده سازی الگوی طراحی Adapter
ایجاد adapter در سوئیفت بسیار آسان است. فقط کافی است object جدیدی ایجاد کنید، object قبلی را در آن بسته بندی کنید و رابط لازم را برای کلاس یا struct جدید خود ایجاد کنید. به عبارتی دیگر، object بسته بندی کننده ما همان adapter است که رابط هدف را با بسته بندی کردن object اصلی، پیاده سازی میکند. پس:
تطبیق پذیر یا Adaptee:
همان object که برای هدف مشخص تطبیق میدهیم. (سوکت usb-a قدیمی)
Adapter:
همان object تطبیق کننده (adapter) که object اصلی را بسته بندی میکند و شرایط جدیدی را که توسط رابط هدف مشخص شده ایجاد میکند (کار اصلی را انجام میدهد، مانند دانگل usb در عکس بالا)
هدف یا Target:
همان object هدف که میخواهیم object اصلی را با آن استفاده کنیم. (سوکت usb-c)
چگونه از الگوی طراحی Adapter در سوئیفت استفاده کنیم؟
اگر میخواهید از کتابخانه شخص ثالث در برنامه خود استفاده کنید ولی رابط آن با شرایط برنامه سازگار نیست، میتوانید از الگوی adapter استفاده کنید. برای مثال میتوانید کل SDK یا API سرور را بسته بندی کنید تا یک تقسیم کننده مشترک ایجاد شود.
در مثال زیر EKEvent را با یک کلاس adapter بسته بندی میکنیم تا یک protocol جدیدی را پیاده سازی کنیم:
protocol هدف ما:
import Foundation
import EventKit
protocol Event {
var title: String { get }
var startDate: String { get }
var endDate: String { get }
}
Adapter یا همان کلاس بسته بنده کننده:
class EventAdapter {
private lazy var dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy. MM. dd. HH:mm"
return dateFormatter
}()
private var event: EKEvent
init(event: EKEvent) {
self.event = event
}
}
پیاده سازی اصلی Adapter:
extension EventAdapter: Event {
var title: String {
return self.event.title
}
var startDate: String {
return self.dateFormatter.string(from: event.startDate)
}
var endDate: String {
return self.dateFormatter.string(from: event.endDate)
}
}
و طرز استفاده از adapter ایجاد شده به این شکل است که ابتدا یک نمونه از EKEvent تطبیق شده میسازیم:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy HH:mm"
let calendarEvent = EKEvent(eventStore: EKEventStore())
calendarEvent.title = "Adapter tutorial deadline"
calendarEvent.startDate = dateFormatter.date(from: "07/30/2018 10:00")
calendarEvent.endDate = dateFormatter.date(from: "07/30/2018 11:00")
و الان میتوانیم از کلاس adapter به عنوان Event protocol استفاده کنیم به جای EKEvent:
let adapter = EventAdapter(event: calendarEvent)
// adapter.title
// adapter.startDate
// adapter.endDate
مورد دیگر استفاده زمانی است که مجبور باشید از چندین کلاس final یا struct هایی استفاده کنید که بعضی از عملکرد های مورد نیاز را ندارند و میخواهید یک رابط هدف جدید برای آنها ایجاد کنید. پس بسته بندی کردن آنها برای رفع این مشکل انتخاب خوبی میتواند باشد.
و این بود الگوی طراحی Adapter. معمولا پیاده سازی این الگو در سوئیفت (یا هر زبان برنامه نویسی دیگری) آسان است. این الگو بسیار کاربردی و گاهی اجتناب ناپذیر است.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید