将可变类更改为不可变类

时间:2015-08-03 20:42:53

标签: ios objective-c oop design-patterns shared-libraries

我正面临一项架构决策,我需要一些帮助。

我正在创建一个将由多个客户端使用的库。在这个库中,我有一个名为LibClass的类,其中包含一个名为aProperty的读写属性,以及一个名为LibManager的类,它包含对Libclass实例的引用。 LibManager负责更新LibClass个属性。

客户可以通过LibClass上的方法获取LibManager个实例,让我们称之为getLibClassInstanceMethod

我不希望我的客户能够更改aProperty中的LibClass,因为这意味着客户可以更改我的图书馆模型。我只希望LibManager有权更改aProperty

我一直在考虑几个解决方案:

选项1

getLibClassInstanceMethod内返回对象的深层副本。

优点: 我始终确信只有图书馆才能完全访问该模型。

缺点: 内存消耗 - 每次我想获取对象时,我都需要克隆它。

选项2

使LibClass不可变;每次我想对类属性进行更改时,我都需要创建一个新类,并在指定的初始化器(构造函数)中传递新值并销毁旧对象。

优点: 我让这个类变得不可变,这正是我想要的

缺点: 当类变大时,总是重新创建类只是因为一个属性发生了变化,这有点奇怪。

选项3

创建某种可变/不可变对,如NSString / NSMutableString。

优点: 不确定

缺点: 对于每个班级,需要两个班级,使班级数增加一倍。

我真的不确定要走哪条路。你会做什么?

由于

2 个答案:

答案 0 :(得分:2)

这样做的一种方法是杰夫说的。

在LibClass.h里面的界面:

@property (strong, readonly) id aProperty;

在新文件LibClassPrivate.h中:

@interface LibClass ()
@property (strong, readwrite) id aPropertyWritable;
@end

在LibClass.m中:

@implementation LibClass{
    id _aProperty;
}

- (id) aProperty{
    return [_aProperty copy];
}

- (void) setAPropertyWritable: (id) aPropertyWritable {
    _aProperty = aPropertyWritable;
}
- (id) aPropertyWritable{
    return _aProperty;
}
@end

基本上,我们有两个属性。两者都由一个实例变量支持。在我们的公共标题中显示的那个只能返回ivar的副本。在我们的私人标题中显示的那个可以读取和写入ivar。无论什么类需要能够使用读写访问器,只需将#import私有标头放入其.m文件中。

确保无论何种类型的对象_aProperty都实现了copyWithZone:。

顺便说一下,即使是Apple也提到了这种方法。

  

如果您打算提供“私人”方法或属性   选择其他类,例如框架内的相关类   可以在单独的头文件中声明类扩展并导入   它在需要它的源文件中。有两个人并不罕见   例如,一个类的头文件,例如XYZPerson.h和   XYZPersonPrivate.h。当您发布框架时,您只能发布   公共XYZPerson.h头文件。

答案 1 :(得分:0)

怎么样??

.h文件

@property (strong, nonatomic, readonly) id lib;

.m文件

@interface LibManager ()
@property (strong, nonatomic, readwrite) id lib;
@end

@implementation LibManager
@synthesize lib = _lib;
// ...

- (id)lib
{
    return [_lib copy];
}

- (id)_internal_get_mutable_lib
{
    return _lib;
}
@end