享元模式的定义:用共享的技术有效地支持大量细粒度的对象。
认识享元模式:
1、变与不变
享元模式的设计重点就在于分享变与不变。把一个对象分离为内部状态和外部状态,内部状态是不变的,外部状态是可变的。然后通过共享不变的部分,以达到节约空间的目的。
2、共享与不共享
在享元模式中,又有共享和不共享之分。有时还可以把共享的享元对象组合成一个组合对象,这样的组合对象可以不用共享,需要时创建他就可以了。
3、内部状态和外部状态
内部状态是享元对象内部的属性、状态,是不变的,所以可以共享。
外部状态是享元对象外部的状态,取决于使用的场景,会根据使用场景而变化,所以不可以共享。
4、实例池
在享元模式中,会创建一个享元工厂,用它来管理、创建和清理享元对象。享元对象就缓存在这个工厂中。这个享元工厂的难度在于何时清理不再需要或者是长时间不再需要的享元对象,可以选择使用长时间不用的享元对象,就把它清理掉。
如果一个程序使用了大量的对象,这些大量的对象造成了很大的存储开销时就应该考虑使用。关键点在于透过现像看到问题的本质,很多情况下,这些对象并不是完全相同的,每一个对象的状态并不相同,享元模式的关键在于把对象中相同的部分抽像出来进行共享,并美其名旦“内部状态”,这些内部状态就是用来共享的,那么那些不同的状态呢?美其名旦“外部状态”,把外部状态的处理交给客户端(也就是调用方,也叫上下文)。使用这种模式无疑会使用程序的复杂度上升许多,但是没办法,设计模式本来就是一种权衡。
各种设计模式的书上都把享元模式的应用场景想象成了在文字处理程序中。下面的我使用oc来实现一下。
这个是用来保存外部状态的“字符状态类”
@interface CharacterState : NSObject
@property (nonatomic, assign) NSInteger fontSize;
@property (nonatomic, copy) NSString *fontColor;
@end
@implementation CharacterState
@end
这个是享元类,字符对象提供一个使用的接口
@class CharacterState;
@interface FlyWeight : NSObject
-(void)show:(CharacterState*)cState;
@end
@implementation FlyWeight
-(void)show:(CharacterState*)cState
{
}
@end
这个是具体的字符享元类
@class CharacterState;
@interface CharacterFlyWeight : FlyWeight
@property (nonatomic, copy) NSString *character;
-(void)show:(CharacterState*)cState;
@end
@implementation CharacterFlyWeight
-(void)show:(CharacterState*)cState
{
NSLog(@"%@, color:%@ -- fontSize: %tu", self.character, cState.fontColor, cState.fontSize);
}
@end
这个是创建字符的享元工厂
@class FlyWeight;
@interface CharactorFactory : NSObject
-(FlyWeight*)createCharacter:(NSString*)character;
@end
@interface CharactorFactory ()
@property (nonatomic, strong) NSMutableDictionary *flyWeightsDict;
@end
@implementation CharactorFactory
-(NSMutableDictionary *)flyWeightsDict
{
if(_flyWeightsDict==nil)
{
_flyWeightsDict = [NSMutableDictionary dictionary];
}
return _flyWeightsDict;
}
-(FlyWeight*)createCharacter:(NSString*)character
{
CharacterFlyWeight * characterFlyWeight = self.flyWeightsDict[character];
if(characterFlyWeight==nil)
{
characterFlyWeight =[[CharacterFlyWeight alloc]init];
characterFlyWeight.character = character;
self.flyWeightsDict[character] = characterFlyWeight;
}
return characterFlyWeight;
}
@end
这个是上下文
CharactorFactory *factory = [[CharactorFactory alloc]init];
[factory createCharacter:@"a"];
[factory createCharacter:@"b"];
FlyWeight *character = [factory createCharacter:@"c"];
//生成一个用来保存外部状态的对象
CharacterState *state = [[CharacterState alloc]init];
state.fontSize = 12;
state.fontColor = @"红色";
//根据外部状态显示文字
[character show:state];