试图了解何时何地不使用单例
Tryning to understand when and when to not use a singleton
有很多关于单例的信息,什么时候使用它,为什么不应该使用它等等。所以希望能更好地理解它,也许有人可以用我正在使用的应用程序中的示例来解释它制作.
我正在使用 Parse 创建一个需要用户注册的应用程序。如果我以这种方式使用单身人士,这是好事还是坏事?我在想我将使用我的 User
class 在整个应用程序中执行与用户相关的操作,也许创建 User
class 的实例一次是个好主意:
// User.h
@interface User : NSObject
+ (instancetype)sharedInstance;
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email;
@end
// User.m
#import "User.h"
#import <Parse/Parse.h>
@implementation User
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
NSLog(@"sharedInstance User.m");
});
return sharedInstance;
}
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email {
// Create a new user
PFUser *newUser = [PFUser user];
newUser.username = username;
newUser.password = password;
// Additional user information
newUser[@"email"] = email;
[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// Hooray! Let them use the app now.
NSLog(@"Success created user: %@", newUser);
} else {
NSString *errorString = [error userInfo][@"error"];
// Show the errorString somewhere and let the user try again.
NSLog(@"Error: %@", errorString);
}
}];
}
@end
// LoginViewController.m
#pragma mark - IBActions
- (IBAction)loginButtonClicked:(UIButton *)sender
{
[[User sharedInstance] createNewUser:self.usernameTextField.text
password:self.passwordTextField.text
email:self.emailTextField.text];
}
或者这样做更好:
// User.h
@interface User : NSObject
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email;
@end
// User.m
@implementation User
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email {
// Create a new user
PFUser *newUser = [PFUser user];
newUser.username = username;
newUser.password = password;
// Additional user information
newUser[@"email"] = email;
[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// Hooray! Let them use the app now.
NSLog(@"Success created user: %@", newUser);
} else {
NSString *errorString = [error userInfo][@"error"];
// Show the errorString somewhere and let the user try again.
NSLog(@"Error: %@", errorString);
}
}];
}
@end
// LoginViewController.m
- (IBAction)loginButtonClicked:(UIButton *)sender
{
User *newUser = [User new];
[newUser createNewUser:self.usernameTextField.text
password:self.passwordTextField.text
email:self.emailTextField.text];
}
此外,如果我滥用了任何方法,请指出,感谢您的诚实!
当你想把某样东西做成单例时,这样想:
- 这个class会真的每次申请一个永远吗? (在你的情况下,我可以看到,例如,一段时间后你会希望管理员以你的应用程序的某个用户身份登录,你最终会得到两个用户对象)
- 这个class会不会真的永远简单到我不会遭受单例测试和全局问题(单例使单元测试变得困难,并且它们将全局实体添加到您的程序中,从而难以跟踪各个应用程序部分对其所做的更改)
如果任一选项适用于您的情况,请执行以下操作:
- 不要让 class 成为单身人士
- 使用依赖注入容器或注册表模式将您的 class 绑定到它,并始终根据容器/注册表
解析 class
有很多关于单例的信息,什么时候使用它,为什么不应该使用它等等。所以希望能更好地理解它,也许有人可以用我正在使用的应用程序中的示例来解释它制作.
我正在使用 Parse 创建一个需要用户注册的应用程序。如果我以这种方式使用单身人士,这是好事还是坏事?我在想我将使用我的 User
class 在整个应用程序中执行与用户相关的操作,也许创建 User
class 的实例一次是个好主意:
// User.h
@interface User : NSObject
+ (instancetype)sharedInstance;
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email;
@end
// User.m
#import "User.h"
#import <Parse/Parse.h>
@implementation User
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
NSLog(@"sharedInstance User.m");
});
return sharedInstance;
}
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email {
// Create a new user
PFUser *newUser = [PFUser user];
newUser.username = username;
newUser.password = password;
// Additional user information
newUser[@"email"] = email;
[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// Hooray! Let them use the app now.
NSLog(@"Success created user: %@", newUser);
} else {
NSString *errorString = [error userInfo][@"error"];
// Show the errorString somewhere and let the user try again.
NSLog(@"Error: %@", errorString);
}
}];
}
@end
// LoginViewController.m
#pragma mark - IBActions
- (IBAction)loginButtonClicked:(UIButton *)sender
{
[[User sharedInstance] createNewUser:self.usernameTextField.text
password:self.passwordTextField.text
email:self.emailTextField.text];
}
或者这样做更好:
// User.h
@interface User : NSObject
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email;
@end
// User.m
@implementation User
- (void)createNewUser:(NSString *)username password:(NSString *)password email:(NSString*)email {
// Create a new user
PFUser *newUser = [PFUser user];
newUser.username = username;
newUser.password = password;
// Additional user information
newUser[@"email"] = email;
[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// Hooray! Let them use the app now.
NSLog(@"Success created user: %@", newUser);
} else {
NSString *errorString = [error userInfo][@"error"];
// Show the errorString somewhere and let the user try again.
NSLog(@"Error: %@", errorString);
}
}];
}
@end
// LoginViewController.m
- (IBAction)loginButtonClicked:(UIButton *)sender
{
User *newUser = [User new];
[newUser createNewUser:self.usernameTextField.text
password:self.passwordTextField.text
email:self.emailTextField.text];
}
此外,如果我滥用了任何方法,请指出,感谢您的诚实!
当你想把某样东西做成单例时,这样想:
- 这个class会真的每次申请一个永远吗? (在你的情况下,我可以看到,例如,一段时间后你会希望管理员以你的应用程序的某个用户身份登录,你最终会得到两个用户对象)
- 这个class会不会真的永远简单到我不会遭受单例测试和全局问题(单例使单元测试变得困难,并且它们将全局实体添加到您的程序中,从而难以跟踪各个应用程序部分对其所做的更改)
如果任一选项适用于您的情况,请执行以下操作:
- 不要让 class 成为单身人士
- 使用依赖注入容器或注册表模式将您的 class 绑定到它,并始终根据容器/注册表 解析 class