1. 程式人生 > >享元模式 flyweight

享元模式 flyweight

享元模式的定義:用共享的技術有效地支援大量細粒度的物件。

認識享元模式:

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];