iOS設計模式 (四)享元模式

weixin_34239169發表於2018-05-12
  • 享元模式(英語:Flyweight Pattern)。使用共享物件,減少同一類物件的大量建立,儘可能減少記憶體使用量以及分享資訊給儘可能多的相似物件,運用共享技術有效地支援大量細粒度的物件。
  • 享元模式UML


    6850908-cf11df3d685490df.png
    4.png
  • 實現享元模式需要兩個關鍵元件,
    1.可攻享享元物件
    2.享元池
    工廠是這一角色的理想候選。它可以通過一個工廠方法,根據父型別返回各種型別的具體享元物件,其主要的目的就是使用池中的享元物件,並適當地從中返回享元物件。
  • 享元模式的使用場景
    @:應用程式使用很多物件。
    @:在記憶體中儲存物件會影響記憶體效能。
    @:物件的多數特有狀態可以放到外部而輕量化。
    @:移除了外在狀態後,可以用較少的共享物件替代原來的那組物件。
    @:應用程式不依賴於物件標識,因為共享物件不能提供唯一的標識。

享元模式的例項應用

  • User類
#import <Foundation/Foundation.h>

@interface User : NSObject

@property (nonatomic, copy)NSString *useName;

@end
#import "User.h"

@implementation User

@end
  • FlySiteProtocol 協議
#import <Foundation/Foundation.h>
#import "User.h"

@protocol FlySiteProtocol <NSObject>

- (void)use:(User *)user;

@end
  • ConcreteFlySite 類
#import <Foundation/Foundation.h>
#import "FlySiteProtocol.h"

@interface ConcreteFlySite : NSObject <FlySiteProtocol>

@property (nonatomic, copy) NSString *webName;

@end
#import "ConcreteFlySite.h"


@implementation ConcreteFlySite

- (void)use:(User *)user
{
    NSLog(@"網站分類:%@ 使用者名稱字:%@", self.webName, user.useName);
}

@end
  • FlyWeightFactory 工廠類
#import <Foundation/Foundation.h>
#import "FlySiteProtocol.h"

@interface FlyWeightFactory : NSObject

@property (nonatomic, strong) NSDictionary *flyweights; //共享物件

- (id <FlySiteProtocol>)flyWeightCategory:(NSString *) webKey;

- (NSInteger )getWebSiteCount;
@end

#import "FlyWeightFactory.h"
#import "ConcreteFlySite.h"

@implementation FlyWeightFactory

- (instancetype)init
{
    self = [super init];
    if (self) {
        _flyweights= [NSDictionary dictionary];
    }
    return self;
}

- (id <FlySiteProtocol>)flyWeightCategory:(NSString *)webKey
{
    __block id <FlySiteProtocol> webFlySet = nil;
    
    [self.flyweights enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if (webKey == key) {
            webFlySet = obj;
            * stop = YES;
        }
    }];
    
    if (webFlySet == nil) {
        ConcreteFlySite *concrete = [[ConcreteFlySite alloc] init];
        concrete.webName = webKey;
        webFlySet = concrete;
        
        NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:self.flyweights];
        [mutableDict setObject:webFlySet forKey:webKey];
        self.flyweights = [NSDictionary dictionaryWithDictionary:mutableDict];
    }
    
    return webFlySet;
    
}

- (NSInteger)getWebSiteCount {
    return self.flyweights.count;
}

@end
  • ViewController 類
#import "ViewController.h"
#import "FlyWeightFactory.h"
#import "ConcreteFlySite.h"
#import "User.h"
#import "FlySiteProtocol.h"

typedef id <FlySiteProtocol> WebsiteType;

@interface ViewController ()

@end

@implementation ViewController


- (NSArray *)testArray
{
    NSMutableArray *array = [NSMutableArray array];
    
    for (NSInteger i =  0; i < 5000; i ++) {
        if (i %2 == 0) {
            [array addObject:[NSString stringWithFormat:@"訂單%ld",(long)i]];
        }
        else {
            [array addObject:[NSString stringWithFormat:@"訂單%ld",(long)i]];
        }
    }
    
    return array;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 通過工廠方法返回各種具體享元物件,維護池中的享元物件
    FlyWeightFactory *factory = [[FlyWeightFactory alloc] init];
    
    
    for (NSInteger i = 0; i < [self testArray].count; i++ ) {
        WebsiteType type  = [factory flyWeightCategory:[self testArray][i]];
        User *user = [[User alloc] init];
        user.useName = [NSString stringWithFormat:@"使用者%ld",i];
        [type use:user];
    }
    
//     WebsiteType type1 =  [factory flyWeightCategory:@"首頁"];
//
//    NSLog(@"factroy=====:%ld",[factory getWebSiteCount]);
//
////    //  返回具體的享元物件
//
//    User *user1 = [[User alloc] init];
//    user1.useName = @"張三";
//    // 享元物件都具有use方法
//    [type1 use:user1];
//
//    WebsiteType type2 = [factory flyWeightCategory:@"商店"];
//    User *user2 = [[User alloc] init];
//    user2.useName = @"李四";
//    [type2 use:user2];
//
//     NSLog(@"factroy111=====:%ld",[factory getWebSiteCount]);
}
@end

相關文章