Cowboy Tech

iOS设计模式-享元

享元模式

交叉的圆环,提取出公共部分进行复用。

  1. 定义:享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。
  2. 步骤: 共享物件的提取 —> 管理共享对象 —> 获取共享对象

@interface ViewController ()

@property(nonatomic,strong) NSMutableDictionary *flyweightFactory;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

self.flyweightFactory = [NSMutableDictionary dictionary];

[self.flyweightFactory setObject:[Model new] forKey:@"A"];

//方式一: 直接提取
//    NSLog(@"%@",self.flyweightFactory[@"A"]);
//    NSLog(@"%@",self.flyweightFactory[@"A"]);


//方式二: 享元模式(有,则返回,无则创建返回)
NSLog(@"%@",[self ModelWithName:@"A"]);
NSLog(@"%@",[self ModelWithName:@"A"]);
}

- (id)ModelWithName:(NSString *)name {

if (self.flyweightFactory[name]==nil) {

    self.flyweightFactory[name] = [Model new];

    return self.flyweightFactory[name];

}else{

    return self.flyweightFactory[name];

}       
}
@end

咖啡厅案例

分析创建咖啡菜单,相当于一个池子,将所有的享元咖啡存储在里面

共享同种类的对象,三种对象:

  1. 咖啡店
  2. 咖啡table
  3. 咖啡清单

CoffeeFlavor

@interface CoffeeFlavor : NSObject
@property (nonatomic, strong) NSString *flavor;
@end

Menu (相当于一个池子,将所有的享元咖啡存储在里面)

@interface Menu : NSObject

//获取指定味道的咖啡(如果没有则创建)
- (CoffeeFlavor *)lookupWithFlavor:(NSString *)flavor;
@end

@interface Menu ()
@property (nonatomic, strong) NSMutableDictionary <NSString *, CoffeeFlavor *>  *flavors;
@end

@implementation Menu

- (instancetype)init {   
    self = [super init];  
    if (self) {  
        self.flavors = [NSMutableDictionary dictionary];
    }   
    return self;
}

- (CoffeeFlavor *)lookupWithFlavor:(NSString *)flavor {
    NSParameterAssert(flavor);
    if ([self.flavors objectForKey:flavor] == nil) {       
        CoffeeFlavor *coffeeFlavor = [[CoffeeFlavor alloc] init];
        coffeeFlavor.flavor        = flavor;     
        self.flavors[flavor] = coffeeFlavor;
    }  
    return [self.flavors objectForKey:flavor];
}
@end

CoffeeShop

@interface CoffeeShop : NSObject
- (void)takeOrder:(NSString *)flavor table:(int)table;
- (void)serve;
@end

@interface CoffeeShop ()

@property (nonatomic, strong) NSMutableDictionary <NSNumber *, CoffeeFlavor *>  *orders;
@property (nonatomic, strong) Menu *menu;

@end

@implementation CoffeeShop

- (instancetype)init {  
    self = [super init];
    if (self) { 
        self.orders = [NSMutableDictionary dictionary];
        self.menu   = [[Menu alloc] init];
    }
    return self;
}

- (void)takeOrder:(NSString *)flavor table:(int)table {
    [self.orders setObject:[self.menu lookupWithFlavor:flavor]
                    forKey:@(table)];
}

- (void)serve {
    NSArray *allKeys = self.orders.allKeys;
    for (id key in allKeys) {  
        NSLog(@"[%@] Serving %@ to table %@", [self.orders objectForKey:key], [self.orders objectForKey:key].flavor, key);
    }
}
@end

ViewController

@interface ViewController ()
@property (nonatomic, strong) CoffeeShop *coffeeShop;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 创建咖啡厅
    self.coffeeShop = [[CoffeeShop alloc] init];
    // 相同类型的数据公用
    [self.coffeeShop takeOrder:@"Cappuccino" table:1];
    [self.coffeeShop takeOrder:@"Frappe"     table:10];
    [self.coffeeShop takeOrder:@"Cappuccino" table:6];
    [self.coffeeShop takeOrder:@"Espresso"   table:9];
    [self.coffeeShop takeOrder:@"Frappe"     table:8];

    // 开始服务
    [self.coffeeShop serve];
}
@end

字典属性

@property (nonatomic, strong) NSMutableDictionary <NSString *, CoffeeFlavor *>  *flavors;