Last active
October 9, 2015 16:11
-
-
Save victorpimentel/41f2f0ddec132b14606d to your computer and use it in GitHub Desktop.
Immutable & mutable models
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
@interface TMUser1 : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end | |
@interface TMMutableUser1 : TMUser1 | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end |
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
@interface TMUser1 () | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end | |
@implementation TMUser1 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser1 *)copyWithZone:(NSZone *)zone | |
{ | |
return self; | |
} | |
- (TMMutableUser1 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [[TMMutableUser1 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
@end | |
@implementation TMMutableUser1 | |
@dynamic userId; | |
@dynamic name; | |
@dynamic surname; | |
@dynamic avatarURL; | |
- (TMUser1 *)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMUser1 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
@end |
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
@interface TMUser2 : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end | |
@protocol TMMutableUser2 <NSObject> | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end | |
typedef TMUser2<TMMutableUser2> TMMutableUser2; |
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
@interface TMUser2 () | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end | |
@implementation TMUser2 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser2 *)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMUser2 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
- (TMMutableUser2 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [self copyWithZone:zone]; | |
} | |
@end |
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
@interface TMUser3 : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end | |
@interface TMMutableUser3 : TMUser3 | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end |
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
@implementation TMUser3 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser3 *)copyWithZone:(NSZone *)zone | |
{ | |
return self; | |
} | |
- (TMMutableUser3 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [[TMMutableUser3 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
@end | |
@interface TMMutableUser3 () | |
@property (nonatomic, copy) NSString *mutableUserId; | |
@property (nonatomic, copy) NSString *mutableName; | |
@property (nonatomic, copy) NSString *mutableSurname; | |
@property (nonatomic, copy) NSURL *mutableAvatarURL; | |
@end | |
@implementation TMMutableUser3 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_mutableUserId = [userId copy]; | |
_mutableName = [name copy]; | |
_mutableSurname = [surname copy]; | |
_mutableAvatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser1 *)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMUser1 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
- (NSString *)userId | |
{ | |
return self.mutableUserId; | |
} | |
- (void)setUserId:(NSString *)userId | |
{ | |
self.mutableUserId = userId; | |
} | |
- (NSString *)name | |
{ | |
return self.mutableName; | |
} | |
- (void)setName:(NSString *)name | |
{ | |
self.mutableName = name; | |
} | |
- (NSString *)surname | |
{ | |
return self.mutableSurname; | |
} | |
- (void)setSurname:(NSString *)surname | |
{ | |
self.mutableSurname = surname; | |
} | |
- (NSURL *)avatarURL | |
{ | |
return self.mutableAvatarURL; | |
} | |
- (void)setAvatarURL:(NSURL *)avatarURL | |
{ | |
self.mutableAvatarURL = avatarURL; | |
} | |
@end |
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
@interface TMUser4 : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end | |
@interface TMMutableUser4 : TMUser4 | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end |
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
@interface TMUser4 () | |
{ | |
@protected | |
NSString *_userId; | |
NSString *_name; | |
NSString *_surname; | |
NSURL *_avatarURL; | |
} | |
@end | |
@implementation TMUser4 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser4 *)copyWithZone:(NSZone *)zone | |
{ | |
return self; | |
} | |
- (TMMutableUser4 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [[TMMutableUser4 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
@end | |
@implementation TMMutableUser4 | |
@dynamic userId; | |
@dynamic name; | |
@dynamic surname; | |
@dynamic avatarURL; | |
- (TMUser4 *)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMUser4 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
- (void)setUserId:(NSString *)userId | |
{ | |
_userId = [userId copy]; | |
} | |
- (void)setName:(NSString *)name | |
{ | |
_name = [name copy]; | |
} | |
- (void)setSurname:(NSString *)surname | |
{ | |
_surname = [surname copy]; | |
} | |
- (void)setAvatarURL:(NSURL *)avatarURL | |
{ | |
_avatarURL = avatarURL; | |
} | |
@end |
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
@protocol TMUser5 <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
@end | |
@interface TMMutableUser5 : NSObject <TMUser5> | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end | |
typedef NSObject<TMUser5> TMUser5; |
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
@implementation TMMutableUser5 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (id<TMUser5>)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMMutableUser5 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
- (TMMutableUser5 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [self copyWithZone:zone]; | |
} | |
@end |
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
@interface TMUser6 (Mutability) | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end |
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
@interface TMUser6 : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, copy, readonly) NSString *userId; | |
@property (nonatomic, copy, readonly) NSString *name; | |
@property (nonatomic, copy, readonly) NSString *surname; | |
@property (nonatomic, readonly) NSURL *avatarURL; | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL; | |
@end |
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
@interface TMUser6 () | |
@property (nonatomic, copy) NSString *userId; | |
@property (nonatomic, copy) NSString *name; | |
@property (nonatomic, copy) NSString *surname; | |
@property (nonatomic) NSURL *avatarURL; | |
@end | |
@implementation TMUser6 | |
- (instancetype)initWithUserId:(NSString *)userId | |
name:(NSString *)name | |
surname:(NSString *)surname | |
avatarURL:(NSURL *)avatarURL | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
_userId = [userId copy]; | |
_name = [name copy]; | |
_surname = [surname copy]; | |
_avatarURL = avatarURL; | |
} | |
return self; | |
} | |
- (TMUser6 *)copyWithZone:(NSZone *)zone | |
{ | |
return [[TMUser6 alloc] initWithUserId:self.userId | |
name:self.name | |
surname:self.surname | |
avatarURL:self.avatarURL]; | |
} | |
- (TMUser6 *)mutableCopyWithZone:(NSZone *)zone | |
{ | |
return [self copyWithZone:zone]; | |
} | |
@end |
Yeah, @cesteban, I wrote the ones that kept the NSCopying/NSMutableCopying interface, because I thought that we already voted for it in the arch committee after testing it in the field.
However we can decide it again if we see that other option with a different API will be better for us. That can open a can of worms too :P because then we have another option: to just publish the initialize and that's just it. TMPhoneNumber follows that option, and it has resulted in an explosion of initializers :/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is one more solution not listed here, which is not having mutable objects at all.
How this approach ranks in your categories:
NSURL
and its methods familyURLByAppendingPathComponent:
).This option could be painful for big objects, but none of the others is free from writting stupid boilerplate. And with this approach we have real proper immutable objects, instead of 'workarounds'.
My preference order would be this option first, and if not, then the option #2, which is very weird, and hacky, and murky, but at least is the easiest and shortest. And when it comes to mutable vs. immutable, there is nothing in between. There is nothing like 'half mutable'. Every approach in the list is making objects mutable in one way or another. So if we choose to mutate, let's mutate with the simplest possible approach.