iOS设计模式——享元模式

公共交通(如公共汽车)已有一百多年的历史了。大量去往相同方向的乘客可以分担保有和经营车辆(如公共汽车)的费用。公共汽车有多个站台,乘客沿着路线在接近他们目的地的地方上下车。到达目的地的费用仅与行程有关。跟保有车辆相比,乘坐公共汽车要便宜得多。这就是利用公共资源的好处。

在面向对象软件设计中,我们利用公共对象不仅能节省资源还能提高性能。比方说,某个人物需要一个类的一百万个实例,但我们可以把这个类的一个实例让大家共享,而把某些独特的信息放在外部,节省的资源可能相当可观(一个实例与一百万个实例的差别)。共享的对象只提供某些内在的信息,而不能用来识别对象。专门用于设计可共享对象的一种设计模式叫做享元模式。

何为享元模式?

实现享元模式需要两个关键组件,通常是可共享的享元对象和保存它们的池。某种中央对象为何这个池,并从它返回适当的实例。工厂是这一角色的理想候选。它可以通过一个工厂方法,根据父类型返回各种类型的具体享元对象,其主要的目的就是为何池中的享元对象,并适当地从中返回享元对象。

使得享元对象是轻量级的最重要原因是什么呢?不是它们的大小,而是通过共享能够节省的空间总量。某些对象的独特状态可以拿到外部,在别处管理,其余部分被共享。比如说,原来需要一个类的一百万个对象,但因为这个类的对象为享元,现在只要一个就够了。这就是由于可共享的享元对象让整个系统变得轻量的原因。通过仔细的设计,内存的节省非常可观。在iOS开发中,节省内存意味着提升整体性能。

享元模式:运用共享技术有效地支持大量细粒度的对象。

何时使用享元模式?

@:应用程序使用很多对象。

@:在内存中保存对象会影响内存性能。

@:对象的多数特有状态可以放到外部而轻量化。

@:移除了外在状态后,可以用较少的共享对象替代原来的那组对象。

@:应用程序不依赖于对象标识,因为共享对象不能提供唯一的标识。

享元模式的实例应用

我们创建一个WebSiteFactory工厂类,来维护池中的享元对象,根据父类型返回各种类型的具体享元对象,代码如下:

#import <Foundation/Foundation.h>
#import "WebSiteProtocol.h"
@interface WebSiteFactory : NSObject

@property (nonatomic, strong) NSDictionary *flyweights; //共享对象

- (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方法可以返回具体的享元对象,返回的这个享元对象同时遵守WebSiteProtocol的协议,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(@"网站分类:%@ 用户名字:%@", 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

至此,享元模式的代码已经完成了,我们来看下在客户端怎么使用享元模式,代码如下:

#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];
    // 通过工厂方法返回各种具体享元对象,维护池中的享元对象
    WebSiteFactory *factory = [[WebSiteFactory alloc] init];
    
    // 返回具体的享元对象
    WebsiteType type1 = [factory getWebSiteCategory:@"首页"];
    User *user1 = [[User alloc] init];
    user1.userName = @"张三";
    // 享元对象都具有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(@"个数: %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] 网站分类:首页 用户名字:张三
2015-09-12 15:59:55.322 FlyweightPattern[42020:1723017] 网站分类:商店 用户名字:李四
2015-09-12 15:59:55.322 FlyweightPattern[42020:1723017] 网站分类:案例 用户名字:王五
2015-09-12 15:59:55.323 FlyweightPattern[42020:1723017] 个数: 3

分享相同的资源以执行任务,可能比使用个人的资源完成同样的事情更加高效。享元模式可以通过共享一部分必需的对象,来节省大量的内存。

Demo链接地址:https://github.com/guoshimeihua/FlyweightPattern.git

时间: 2024-07-29 00:24:02

iOS设计模式——享元模式的相关文章

设计模式——享元模式

Flyweight 直译为蝇量.就其表示的模式来说,翻译成享元,确实是不错的 package designpattern.structure.flyweight; public interface Flyweight { void action(int arg); } package designpattern.structure.flyweight; public class FlyweightImpl implements Flyweight { public void action(int

8. 星际争霸之php设计模式--享元模式

题记==============================================================================本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦! 本文地址:http://www.cnblogs.com/davidhhuan/p/4248186.html============================================

[工作中的设计模式]享元模式模式FlyWeight

一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 享元模式:主要为了在创建对象时,对共有对象以缓存的方式进行保存,对外部对象进行单独创建 模式要点: 1.享元模式中的对象分为两部分:共性部分和个性化部分,共性部分就是每个对象都一致的或者多个对象可以共享的部分,个性化部分指差异比较大,每个类均不同的部分 2.共性部分的抽象就是此模

设计模式-享元模式

***********************************************声明****************************************************** 原创作品,出自 "晓风残月xj" 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj). 由于各种原因,可能存在诸多不足,欢迎斧正! *******************************************

设计模式——享元模式详解

0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦~本文原创,转载请注明出处为SEU_Calvin的博客. 春运买火车票是一件疯狂的事情,同一时刻会有大量的查票请求涌向服务器,服务器必须做出应答来满足我们的购票需求.试想,这些请求包含着大量的重复,比如从A地到B地的车票情况,如果每次都重复创建一个车票查询结果的对象,那么GC任务将非常繁重,影响性能

C#设计模式-享元模式

前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡“Design Pattern(设计模式)”? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻理解其中的

小菜学设计模式——享元模式

背景 如果一个应用程序中使用了大量的对象,而大量的这些对象造成了恨得的存储开销时就应该考虑这个新是设计模式:享元模式. 1.使用意图 最大限度地减少了尽可能与其他类似的对象多的数据共享内存的使用,换句话说就是通过共享对象达到系统内维护的对象数量减少从而降低了系统的开销.因为是细粒度的控制,所以享元模式不是控制整个实例共享,那为何不用单例呢?而是只是共享对象的部分,不共享的部分称为对象的外部状态,需要外部动态修改这个共享对象. 2.生活实例 围棋的棋子,如果用编程去实现的话,势必要new出很多实例

深入浅出设计模式——享元模式(Flyweight Pattern)

模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.享元模式正是为解决这一类问题而诞生的.享元模式通过共享技术实现相同或相似对象的重用. 在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有

PHP设计模式——享元模式

声明:本系列博客参考资料<大话设计模式>,作者程杰. 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分状态是可以分享.常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元. UML类图: 角色分析: 享元工厂角色(FWFactory):创建并管理BlogModel对象. 所有具体享元父接口角色(BolgModel):接受并作用与外部状态. 具体享元角色(JobsBlog)