Software design patterns có 4 nhóm chính là:
- Creational patterns: tập hợp những loại pattern khởi tạo đối tượng.
- Structural patterns: tập hợp những loại pattern liên quan đến cấu trúc.
- Behavioral patterns: tập hợp những loại pattern liên quan đến những hành động giữa những đối tượng.
- Concurrency patterns: tập hợp những loại pattern liên quan việc xử lý đồng thời.
Pattern đầu tiên mình muốn giới thiệu với mọi người là Singleton Pattern thuộc Creational pattern.
Khái niệm: Singleton Pattern dùng để khởi tạo một đối tượng (an instance) trong một lớp (a class).
Cấu trúc lớp:
Cách sử dụng:
- Nếu đối tượng mà bạn thường xuyên sử dụng trong ứng dụng bạn có thể dùng singleton pattern. Trước giờ mình hay dùng singleton pattern để tạo lớp quản lý những connection hay database.
- Bạn có thể ứng dụng singleton pattern vào những pattern như: Abstract Factory, Builder, Prototype, Facade và State objects.
- Singleton thường sử dụng trong Facade và State objects.
Code ví dụ trong Objective C: có những cách để tạo đối tượng theo singleton pattern như sau:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Way 1: Get singleton instance using dispatch_once | |
* @author: Cong Pham | |
* @params: None | |
* @return: Object | |
*/ | |
+ (instancetype)sharedInstance { | |
static id singletonInstance = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
singletonInstance = [[self alloc] init]; | |
}); | |
return singletonInstance; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Way 2: Get singleton instance using @synchronized | |
* @author: Cong Pham | |
* @params: None | |
* @return: Object | |
*/ | |
+ (instancetype)sharedInstance { | |
static id singletonInstance = nil; | |
@synchronized(self) { | |
if (!singletonInstance) | |
singletonInstance = [[self alloc] init]; | |
} | |
return singletonInstance; | |
} |
Ngoài ra các bạn khi đọc code trên mạng có cách viết như sau:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Don't use it for singleton object | |
*/ | |
+ (instancetype)sharedInstance { | |
static id singletonInstance = nil; | |
if(!singletonInstance) { | |
//[NSThread sleepForTimeInterval:2]; //Test singleton on multithreads | |
singletonInstance = [[self alloc] init]; | |
NSLog(@"[Non thread safety] Create singleton instance with address at:%@",singletonInstance); | |
//[NSThread sleepForTimeInterval:2]; //Test singleton on multithreads | |
} | |
return singletonInstance; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)testSingletonInstanceRunConcurrent { | |
//Using dispatch async - background | |
for (int i = 0; i < 10; i++) { | |
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ | |
Management2* object = [Management2 sharedInstance]; | |
object.delegate = self; | |
[object doActionD]; | |
}); | |
} | |
} |
Code ví dụ trong Swift: bạn có thể viết như sau:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Way 1: Class constant | |
* This approach supports lazy initialization because Swift lazily initializes class constants (and variables), and is thread safe by the definition of let. | |
* Class constants were introduced in Swift 1.2. If you need to support an earlier version of Swift, use the nested struct approach below or a global constant. | |
*/ | |
class SWManagement: NSObject { | |
static let sharedInstance = SWManagement() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Way 2: dispatch_once | |
* The traditional Objective-C approach ported to Swift. I'm fairly certain there's no advantage over the nested struct approach but I'm putting it here anyway as I find the differences in syntax interesting. | |
*/ | |
class SWManagement: NSObject { | |
class var sharedInstance: SWManagement { | |
struct Static { | |
static var onceToken: dispatch_once_t = 0 | |
static var instance: SWManagement? = nil | |
} | |
dispatch_once(&Static.onceToken) { | |
Static.instance = SWManagement() | |
} | |
return Static.instance! | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Way 3: Nested struct | |
* Here we are using the static constant of a nested struct as a class constant. This is a workaround for the lack of static class constants in Swift 1.1 and earlier, and still works as a workaround for the lack of static constants and variables in functions. | |
*/ | |
class SWManagement: NSObject { | |
class var sharedInstance: SWManagement { | |
struct Singleton { | |
static let instance = SWManagement() | |
} | |
return Singleton.instance | |
} | |
} |
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.