詳解iOS App設(shè)計(jì)模式開(kāi)發(fā)中對(duì)于享元模式的運(yùn)用
享元模式的概念
在面向?qū)ο筌浖O(shè)計(jì)中,利用公共對(duì)象不僅能節(jié)省資源還能提高性能。共享的對(duì)象只能提供某些內(nèi)在的信息,而不能用來(lái)識(shí)別對(duì)象。專(zhuān)門(mén)用于設(shè)計(jì)可共享對(duì)象的一種設(shè)計(jì)模式叫做享元模式(Flyweight pattern)。
實(shí)現(xiàn)享元模式需要兩個(gè)關(guān)鍵組件,通常是可共享的享元對(duì)象和保存他們的池。某種中央對(duì)象維護(hù)這個(gè)池,并從它返回適當(dāng)?shù)膶?shí)例。
運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。
公共交通(如公共汽車(chē))已有一百多年的歷史了。大量去往相同方向的乘客可以分擔(dān)保有和經(jīng)營(yíng)車(chē)輛(如公共汽車(chē))的費(fèi)用。公共汽車(chē)有多個(gè)站臺(tái),乘客沿著路線在接近他們目的地的地方上下車(chē)。到達(dá)目的地的費(fèi)用僅與行程有關(guān)。跟保有車(chē)輛相比,乘坐公共汽車(chē)要便宜得多。這就是利用公共資源的好處。
在面向?qū)ο筌浖O(shè)計(jì)中,我們利用公共對(duì)象不僅能節(jié)省資源還能提高性能。比方說(shuō),某個(gè)人物需要一個(gè)類(lèi)的一百萬(wàn)個(gè)實(shí)例,但我們可以把這個(gè)類(lèi)的一個(gè)實(shí)例讓大家共享,而把某些獨(dú)特的信息放在外部,節(jié)省的資源可能相當(dāng)可觀(一個(gè)實(shí)例與一百萬(wàn)個(gè)實(shí)例的差別)。共享的對(duì)象只提供某些內(nèi)在的信息,而不能用來(lái)識(shí)別對(duì)象。專(zhuān)門(mén)用于設(shè)計(jì)可共享對(duì)象的一種設(shè)計(jì)模式叫做享元模式。
使得享元對(duì)象是輕量級(jí)的最重要原因是什么呢?不是它們的大小,而是通過(guò)共享能夠節(jié)省的空間總量。某些對(duì)象的獨(dú)特狀態(tài)可以拿到外部,在別處管理,其余部分被共享。比如說(shuō),原來(lái)需要一個(gè)類(lèi)的一百萬(wàn)個(gè)對(duì)象,但因?yàn)檫@個(gè)類(lèi)的對(duì)象為享元,現(xiàn)在只要一個(gè)就夠了。這就是由于可共享的享元對(duì)象讓整個(gè)系統(tǒng)變得輕量的原因。通過(guò)仔細(xì)的設(shè)計(jì),內(nèi)存的節(jié)省非??捎^。在iOS開(kāi)發(fā)中,節(jié)省內(nèi)存意味著提升整體性能。
享元模式的實(shí)例應(yīng)用
我們創(chuàng)建一個(gè)WebSiteFactory工廠類(lèi),來(lái)維護(hù)池中的享元對(duì)象,根據(jù)父類(lèi)型返回各種類(lèi)型的具體享元對(duì)象,代碼如下:
#import <Foundation/Foundation.h>
#import "WebSiteProtocol.h"
@interface WebSiteFactory : NSObject
@property (nonatomic, strong) NSDictionary *flyweights; //共享對(duì)象
- (id<WebSiteProtocol>)getWebSiteCategory:(NSString *)webKey;
- (NSInteger)getWebSiteCount;
@end
#import "WebSiteFactory.h"
#import "ConcreteWebSite.h"
@implementation WebSiteFactory
- (instancetype)init {
self = [super init];
if (self) {
_flyweights = [NSDictionary dictionary];
}
return self;
}
- (id<WebSiteProtocol>)getWebSiteCategory:(NSString *)webKey {
__block id<WebSiteProtocol> webset = nil;
[self.flyweights enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (webKey == key) {
webset = obj;
*stop = YES;
}
}];
if (webset == nil) {
ConcreteWebSite *concreteWebset = [[ConcreteWebSite alloc] init];
concreteWebset.webName = webKey;
webset = concreteWebset;
NSMutableDictionary *mutabledic = [NSMutableDictionary dictionaryWithDictionary:self.flyweights];
[mutabledic setObject:webset forKey:webKey];
self.flyweights = [NSDictionary dictionaryWithDictionary:mutabledic];
}
return webset;
}
- (NSInteger)getWebSiteCount {
return self.flyweights.count;
}
@end
代碼中的getWebSiteCategory方法可以返回具體的享元對(duì)象,返回的這個(gè)享元對(duì)象同時(shí)遵守WebSiteProtocol的協(xié)議,WebSiteProtocol的代碼如下:
#import <Foundation/Foundation.h>
#import "User.h"
@protocol WebSiteProtocol <NSObject>
- (void)use:(User *)user;
@end
ConcreteWebSite的代碼如下:
#import <Foundation/Foundation.h>
#import "WebSiteProtocol.h"
@interface ConcreteWebSite : NSObject <WebSiteProtocol>
@property (nonatomic, copy) NSString *webName;
@end
#import "ConcreteWebSite.h"
@implementation ConcreteWebSite
- (void)use:(User *)user {
NSLog(@"網(wǎng)站分類(lèi):%@ 用戶(hù)名字:%@", self.webName, user.userName);
}
@end
User的代碼如下:
#import <Foundation/Foundation.h>
@interface User : NSObject
@property (nonatomic, copy) NSString *userName;
@end
#import "User.h"
@implementation User
@end
至此,享元模式的代碼已經(jīng)完成了,我們來(lái)看下在客戶(hù)端怎么使用享元模式,代碼如下:
#import "ViewController.h"
#import "WebSiteProtocol.h"
#import "WebSiteFactory.h"
#import "ConcreteWebSite.h"
#import "User.h"
typedef id<WebSiteProtocol> WebsiteType;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 通過(guò)工廠方法返回各種具體享元對(duì)象,維護(hù)池中的享元對(duì)象
WebSiteFactory *factory = [[WebSiteFactory alloc] init];
// 返回具體的享元對(duì)象
WebsiteType type1 = [factory getWebSiteCategory:@"首頁(yè)"];
User *user1 = [[User alloc] init];
user1.userName = @"張三";
// 享元對(duì)象都具有use方法
[type1 use:user1];
WebsiteType type2 = [factory getWebSiteCategory:@"商店"];
User *user2 = [[User alloc] init];
user2.userName = @"李四";
[type2 use:user2];
WebsiteType type3 = [factory getWebSiteCategory:@"案例"];
User *user3 = [[User alloc] init];
user3.userName = @"王五";
[type3 use:user3];
NSInteger count = [factory getWebSiteCount];
NSLog(@"個(gè)數(shù): %ld", (long)count);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
輸出如下:
2015-09-12 15:59:55.322 FlyweightPattern[42020:1723017] 網(wǎng)站分類(lèi):首頁(yè) 用戶(hù)名字:張三 2015-09-12 15:59:55.322 FlyweightPattern[42020:1723017] 網(wǎng)站分類(lèi):商店 用戶(hù)名字:李四 2015-09-12 15:59:55.322 FlyweightPattern[42020:1723017] 網(wǎng)站分類(lèi):案例 用戶(hù)名字:王五 2015-09-12 15:59:55.323 FlyweightPattern[42020:1723017] 個(gè)數(shù): 3
分享相同的資源以執(zhí)行任務(wù),可能比使用個(gè)人的資源完成同樣的事情更加高效。享元模式可以通過(guò)共享一部分必需的對(duì)象,來(lái)節(jié)省大量的內(nèi)存。
何時(shí)使用享元模式
(1)應(yīng)用程序使用很多對(duì)象;
(2)在內(nèi)存中保存對(duì)象會(huì)影響內(nèi)存性能;
(3)對(duì)象的多數(shù)特有狀態(tài)(外在狀態(tài))可以放到外部而輕量化;
(3)移除了外在狀態(tài)后,可以用較少的共享對(duì)象替代原來(lái)的那組對(duì)象;
(4)應(yīng)用程序不依賴(lài)于對(duì)象標(biāo)示,因?yàn)楣蚕韺?duì)象不能提供唯一的標(biāo)示。
- 輕松掌握J(rèn)avaScript享元模式
- 總結(jié)JavaScript設(shè)計(jì)模式編程中的享元模式使用
- 詳解Java設(shè)計(jì)模式編程中的Flyweight享元模式的開(kāi)發(fā)結(jié)構(gòu)
- C++設(shè)計(jì)模式編程之Flyweight享元模式結(jié)構(gòu)詳解
- 學(xué)習(xí)JavaScript設(shè)計(jì)模式之享元模式
- JS實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)館享元模式實(shí)例
- Java設(shè)計(jì)模式之共享模式/享元模式(Flyweight模式)介紹
- 深入理解JavaScript系列(37):設(shè)計(jì)模式之享元模式詳解
- php設(shè)計(jì)模式 FlyWeight (享元模式)
- 輕松掌握J(rèn)ava享元模式
相關(guān)文章
iOS自動(dòng)生成表格效果的實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了iOS自動(dòng)生成表格效果的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03IOS中MMDrawerController第三方抽屜效果的基本使用示例
這篇文章主要介紹了IOS中MMDrawerController第三方抽屜效果的基本使用示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02iOS如何將UIButton中的圖片與文字上下對(duì)齊詳解
對(duì)于UIButton實(shí)現(xiàn)上顯示圖片,下顯示文字這個(gè)需求估計(jì)各位iOS開(kāi)發(fā)者們都不陌生,所以下面這篇文章主要給大家介紹了關(guān)于iOS如何將UIButton中圖片與文字上下對(duì)齊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10簡(jiǎn)單談?wù)刢/c++中#import、#include和@class的區(qū)別
對(duì)于#import,我想做過(guò)iOS開(kāi)發(fā)的人應(yīng)該都不陌生。在開(kāi)發(fā)過(guò)程中,當(dāng)我們需要聲明某一個(gè)類(lèi)時(shí),都需要去引用。而#imclude的話,在我們學(xué)習(xí)C時(shí)就已經(jīng)知道了,他的作用也是引用聲明的意思。在表面上他們的作用似乎都是一樣的。但是在具體功能實(shí)現(xiàn)方式上,還是有著很大的區(qū)別。2018-01-01IOS實(shí)現(xiàn)點(diǎn)擊滑動(dòng)抽屜效果
這篇文章主要為大家詳細(xì)介紹了IOS實(shí)現(xiàn)點(diǎn)擊滑動(dòng)抽屜效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02IOS 波紋進(jìn)度(waveProgress)動(dòng)畫(huà)實(shí)現(xiàn)
這篇文章主要介紹了IOS 紋進(jìn)度(waveProgress)動(dòng)畫(huà)實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-09-09替代pod update速度慢的lg_pod_plugin安裝使用詳解
這篇文章主要介紹了替代pod update速度慢lg_pod_plugin安裝使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09詳解ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī)
這篇文章主要介紹了詳解ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11iOS WKWebView無(wú)法處理URL Scheme和App Store鏈接的問(wèn)題解決
這篇文章主要給大家介紹了關(guān)于iOS WKWebView無(wú)法處理URL Scheme和App Store鏈接的問(wèn)題解決的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03IOS開(kāi)發(fā)用戶(hù)登錄注冊(cè)模塊所遇到的問(wèn)題
最近和另外一位同事負(fù)責(zé)公司登錄和用戶(hù)中心模塊的開(kāi)發(fā)工作。通過(guò)本文給大家分享IOS開(kāi)發(fā)用戶(hù)登錄注冊(cè)模塊所遇到的問(wèn)題,感興趣的朋友一起學(xué)習(xí)吧2016-01-01