پیاده سازی الگوی طراحی Delegate در سوئیفت
برای این کار به یک protocol(معادل interface در زبان های دیگر) به عنوان نماینده کننده(delegate)، یک نماینده(delegator) که وظایف را نمایندگی کند و یک object که protocol نماینده کننده را پیاده سازی کند نیاز خواهیم داشت. یا یک مثالی ساده تر:
مشتری باگی را گزارش میدهد، مدیر پروژه موضوع را (در Jira یا هر روش دیگر) ایجاد و به برنامه نویس جهت برطرف کردن آن واگذار میکند.
این نمایندگی (delegation) است. وقتی اتفاقی می افتد، delegator (نماینده یا همان مدیر) از منابع خارجی(توسعه دهنده) به وسیله رابط(interface) مشترک (موضوعی که برای هر دوطرف مشکل را توضیح میدهد) استفاده میکند تا به چیزی برسد (برطرف کردن باگ).
برای نشان دادن کارکرد delegation در کد مثال زیر را برسی کنید ( میتوانید در Xcode playground یا ide مورد علاقه خود اجرا کنید):
protocol InputDelegate {
var shouldContinueListening: Bool { get }
func didStartListening()
func didReceive(input: String)
}
class InputHandler {
var delegate: InputDelegate?
func listen() {
self.delegate?.didStartListening()
repeat {
guard let input = readLine() else {
continue
}
self.delegate?.didReceive(input: input)
}
while self.delegate?.shouldContinueListening ?? false
}
}
و سپس delegate در را struct مورد نظر پیاده می کنیم:
struct InputReceiver: InputDelegate {
var shouldContinueListening: Bool {
return true
}
func didStartListening() {
print("👻 Please be nice and say \"hi\", if you want to leave just tell me \"bye\":")
}
func didReceive(input: String) {
switch input {
case "hi":
print("🌎 Hello world!")
case "bye":
print("👋 Bye!")
exit(0)
default:
print("🔍 Command not found! Please try again:")
}
}
}
let inputHandler = InputHandler()
let inputReceiver = InputReceiver()
inputHandler.delegate = inputReceiver
inputHandler.listen()
و به این گونه می توانید الگوی طراحی delegate خود را در سوئیفت پیاده کنید. اپل نیز از چنین الگویی در UICollectionViewDataSource
، UICollectionViewDelegate
و غیره استفاده میکند. موقع توسعه نرم افزار های iOS فقط نیاز دارید تا delegate را پیاده سازی کنید و آنها protocol و delegator را فراهم میکنند.
پراپرتی ها weak، کلاس ها و delegate ها
مدیریت حافظه موضوع بسیار مهمی است بنابراین لازم است هر موقع که از کلاس ها به عنوان delegate استفاده کردید، حتما پراپتی ها را به صورت weak تعریف کنید تا از چرخه ارجاع(reference cycle) و مموری لیک جلوگیری کنید. (تفاوت کلاس و struct در سوئیفت)
protocol InputDelegate: class { /*...*/ }
class InputHandler {
weak var delegate: InputDelegate?
/*...*/
}
class InputReceiver: InputDelegate {
/*...*/
}
کد بالا تغییر یافته کد قبلی است که این بار از کلاس به عنوان delegate استفاده میکند. برای این کار نیاز است که protocol و پراپرتی های داخل delegator کمی تغییر کنند. پس هر وقت خواستید از کلاس ها به عنوان delegate استفاده کنید، حتما پراپرتی ها را به صورت weak تعریف کنید.
همان طور که میبینید الگوی طراحی delegate آسان است ولی میتواند مشکل ساز هم باشد. این الگو به کم کردن وابستگی بین object ها با فراهم کردن رابط(interface) مشترک کمک میکند که می تواند توسط هر کسی که این protocol را پیاده سازی کند، استفاده شود. مقالات بسیار خوبی درباره ی این الگوی طراحی وجود دارند و درصورت علاقه به مطالعه بیشتر حتما آن ها را نیز برسی کنید.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید