در این مقاله قصد داریم الگوی طراحی فرمان (Command) که یک الگوی طراحی رفتاری (Behavioral) است را با مثالی ساده که در سوئیفت پیاده سازی شده است برسی کنیم.
اگر می خواهید یک رابط مشترک برای اقدامات مختلف که بعداً اجرا می شوند ارائه دهید ، الگوی طراحی فرمان (Command) می تواند مناسبت این کار باشد. معمولاً این الگوی طراحی به صورت یک object است که تمام اطلاعات مورد نیاز برای اجرای صحیح عملکرد زیرین را در بر می گیرد.
Command ها اغلب برای مدیریت اقدامات رابط کاربری (User Interface)، ایجاد عملکرد undo/redo یا مدیریت تراکنش ها استفاده می شود. در مثال زیر پیاده سازی الگوی طراحی Command را در سوئیفت با ایجاد یک برنامه command line برای هندل کردن آرگومان های ایموجی دار مشاهده می کنیم:
ابتدا پروتوکل Command را ایجاد میکنیم:
protocol Command {
func execute()
}
سپس یک Command برای کلاس Help ایجاد می کنیم:
class HelpCommand: Command {
func execute() {
Help().info()
}
}
class Help {
func info() {
print("""
🤖 Commander 🤖
v1.0
Available commands:
👉 help This command
👉 ls List documents
Bye! 👋
""")
}
}
و یک Command دیگر نیز برای کلاس List:
class ListCommand: Command {
func execute() {
List().homeDirectoryContents()
}
}
class List {
func homeDirectoryContents() {
let fileManager = FileManager.default
guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Could not open documents directory")
exit(-1)
}
do {
let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
print("\n\t📁 Listing documents directory:\n")
print(fileURLs.map { "\t\t💾 " + $0.lastPathComponent }.joined(separator: "\n\n") + "\n" )
}
catch {
print(error.localizedDescription)
exit(-1)
}
}
}
و در نهایت استفاده از Command های ساخته شده در برنامه اصلی:
class App {
var commands: [String:Command] = [:]
init() {
self.commands["help"] = HelpCommand()
self.commands["ls"] = ListCommand()
}
func run() {
let arguments = CommandLine.arguments[1...]
guard let key = arguments.first, self.commands[key] != nil else {
print("Usage: ./command.swift [\(self.commands.keys.joined(separator: "|"))]")
exit(-1)
}
self.commands[key]!.execute()
}
}
App().run()
اگر این کد ها را در یک فایل سوئیفت ذخیره کنید، می توانید آن را به سادگی با تایپ کردن ./file-name.swift
در پنجره ترمینال مک اجرا کنید. کامپایلر سوئیفت بقیه مراحل را بر عهده خواهد داشت.
موارد استفاده از الگوی طراحی Command در دنیای واقعی:
- رفتار های مختلف دکمه
- رفتار های انتخاب table view و collection ها در UIKit
- جا به جایی بین کنترلر ها
- مدیریت history / عملکرد undo و redo
- مدیریت تراکنش ها
- مدیریت پیشرفت
- wizard ها
همانطور که می بینید این الگوی طراحی می تواند در جا های مختلف اعمال شود. اپل حتی یک کلاس مخصوص برای این منظور به نام NSInvocation ایجاد کرده است، اما متأسفانه به دلیل رفتار پویای سوئیفت، در دسترس نیست. این مورد چندان مهم نیست زیرا شما همیشه می توانید protocol و پیاده سازی مخصوص به خود را بسازید، در بیشتر موارد شما فقط به یک کلاس اضافی نیاز دارید تا منطق command را در زیر برای شما بسته بندی کند.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید