ios中的设计模式之class Clusters

http://www.cocoachina.com/applenews/devnews/2014/0530/8622.html

我对设计模式一直都是一个若有若无的感觉,特别是在手机端开发,觉得用处不是很大,认为设计模式是为了大规模团队合作,分工才能体现出效果。设计模式可以通过分不同的“层”让大家协同开发,相互之间不产生影响。但是最近看法有点改变,觉得还是需要多少了解一些。

 

天天使用的framework确实是一个庞大的项目,从framework的设计中可以找到很多设计模式的影子,而且还是一个很好的生产化的例子。这里先介绍 Class Clusters

 

Class Clusters 几乎涉及到iOS日常的所有开发过程中,也可能正是这样,导致我们很容易把它彻底遗忘。这里就拿最常用的 NSString 来讲。


  1. NSString *string1 = @"helloworld"; 
  2. NSString *string2 = [[NSString alloc] initWithFormat:@":%@", @"helloworld"]; 
  3. NSString *string3 = [NSHomeDirectory() stringByAppendingPathComponent:string1]; 
  4. NSTextStorage *storage = [[NSTextStorage alloc] initWithString:string1]; 
  5. NSString *string4 = [storage string]; 
  6.   
  7. NSLog(@"%@", [[string1 class] description]); 
  8. NSLog(@"%@", [[string2 class] description]); 
  9. NSLog(@"%@", [[string3 class] description]); 
  10. NSLog(@"%@", [[string4 class] description]); 

 

不知道有多少人试过哈,string3的返回还是让我吃了一惊。下面的结果是在Xcode5.1 SDK7.1 下的结果。


  1. _NSCFConstantString 
  2. _NSCFString 
  3. NSPathStore2 
  4. NSBigMutableString 

 

通过上面的方法创建的 NSString 最后都产生了不同的子类。有人可能会奇怪为什么需要不同的 NSString。因为对于大部分的以阅读内容为主的App来讲,很大部分资源消耗在了字符串处理上面(存储,解析,比较等等),所以对于字符串的存储需要有不同的方式来满足不同的情况,这样才能有性能上的提高。

 

Note: 设想一下,在这些场景上面,如果Apple直接把这些类扔给开发者,会有什么问题呢?那么开发者需要自己在不同的场景决定使用不同的子类,不仅学习成本提高,而且也容易生成性能不太好的代码。现在简单的 NSString 就可以直接覆盖上面的所有场景。而且随着iOS的软硬件的后续开发,开发者还可以在不修改代码的情况下获得性能提升。

 

既然看到了它的强大之处,那么就开始了解吧。 既然这是第一篇DesignPattern那么就从最简单开始:

 

Abstract Classes 

这里引用一下Mike的内容

 An abstract class is a class which is not fully functional on its own. It must be subclassed, and
the subclass must fill out the missing functionality.

 

An abstract class is not necessarily an empty shell. It can still contain a lot of functionality all on its own, but it’s not complete without a subclass to fill in the holes.

 

Mike Ash Friday Q&A 2010-03-12: Subclassing Class Clusters

 

Abstract Class 的概念很简单,类中所有的方法不需要全部有具体的实现,相当于定义了很多的接口。比如一开始的 NSString

 

Class Clusters 

 A class cluster is a hierarchy of classes capped off by a public abstract class. The public class
provides an interface and a lot of auxiliary functionality, and then core functionality is implemented by private subclasses. The public class then provides creation methods which return instances of the private subclasses, so that the public class can be
used without knowledge of those subclasses.

 

Mike Ash Friday Q&A 2010-03-12: Subclassing Class Clusters

 

Clusters的角色不仅要实现 Abstract Class 的方法,还需要自己实现自己的特殊化需求。Abstract Class 负责提供一个“外壳”,真正“干活”的就是Cluster class。这样外部就只需要了解Abstract Class就可以了。

 

NSString Benefits

比如 _NSCFConstantString 负责 const string,类似 @”helloworld”这样的字符串。这样的字符串有一个特点,不会被修改,当真正处理的时候,可以分配大小合适的内存,甚至可以分配在只读 data segment上面,而不需要分配在堆上面,如果有相同的字符串引用就可以完全赋值相同的地址。那么在retainCount上面的处理也就和其他字符串处理有很大不同。

 

NSPathStore2 看上去是处理有Path相关的字符串,因为没有源代码,这里我们可以大胆猜测一下,path相关的主要是做字符串的拼接操作,而这些字符串通常很长,占用空间大,但是重复的概率缺很高,那么就可以缓存一些字符串,这样可以减少一些内存的分配释放开销。

 

How to use 

The class cluster architecture involves a trade-off between simplicity and extensibility: Having a few public classes stand in for a
multitude of private ones makes it easier to learn and use the classes in a framework but somewhat harder to create subclasses within any of the clusters.

 

Apple Develpoer Document Cocoa Core Competencies

 

就像Apple文档中提到的,Class Cluster 是在简单和扩展性上面做了一个妥协。Class Clusters 的子类化比较麻烦,而且也看上去也非常trick,Apple 更推荐的方法是用组合的方法来扩展。

 

大家都知道设计模式有一个非常重的坑就是被过渡设计。Class Cluster 可以帮我们

1. 减少了if else 这样缺乏扩展性的代码

2. 增加新功能支持不影响其他代码

 

那么这个非常适合应用在适配上面,比如不同屏幕的适配,不同厂家可能的不同的需求。


  1. + (id)alloc { 
  2.     if ([self class] == [SFSSearchTVC class]) { 
  3.         if ([UIDevice currentDevice] systemMajorVersion] < 7) { 
  4.             return [SFSSearchTVC6 alloc]; 
  5.         } else if ([UIDevice currentDevice] systemMajorVersion] == 7) { 
  6.             return [SFSSearchTVC7 alloc]; 
  7.         } 
  8.     } 
  9.   
  10.     return [super alloc]; 

 

上面是代码来自BJ Miller’s blog  《A Cluster
to Remove Clutter
》 是用于适配iOS6,iOS7的简单例子。

 

Conclusion

很多设计模式都很像,也很容易糊涂,比如工厂模式和Class Clusters在某些地方就很类似,我自己也并不能很好的分清楚。 设计模式的本质是为了解耦。不管使用哪个设计模式,我们最后追求的都是简单、容易维护和扩展的代码。

时间: 2024-07-28 15:43:55

ios中的设计模式之class Clusters的相关文章

iOS App开发中使用设计模式中的单例模式的实例解析_IOS

一.单例的作用顾名思义,单例,即是在整个项目中,这个类的对象只能被初始化一次.它的这种特性,可以广泛应用于某些需要全局共享的资源中,比如管理类,引擎类,也可以通过单例来实现传值.UIApplication.NSUserDefaults等都是IOS中的系统单例. 二.单例模式的两种写法 1,常用写法 #import "LGManagerCenter.h" static LGManagerCenter *managerCenter; @implementation LGManagerCen

iOS 中的 21 种设计模式

iOS 中的 21 种设计模式 对象创建原型(Prototype) 使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象. 1 2 NSArray *array = [[NSArray alloc] initWithObjects:@1, nil]; NSArray *array2 = array.copy; array 就是原型了,array2 以 array 为原型,通过 copy 操作创建了 array2. 当创建的实例非常复杂且耗时,或者新实例和已存在的实例值相同,使用原型模式

iOS应用开发中使用设计模式中的观察者模式的实例_IOS

在软件开发中,无论是那种高级语言中总会伴随着一些最为常用的设计模式,即便就如iOS开发中与我们打交道最多的无非就是单例模式.观察者模式和工厂模式了,当然了其他的设置模式也同样存在在编程的很多地方.下面就就让我们简单的了解下观察者模式吧! 观察者模式本质上时一种发布-订阅模型,用以消除具有不同行为的对象之间的耦合,通过这一模式,不同对象可以协同工作,同时它们也可以被复用于其他地方Observer从Subject订阅通知,ConcreteObserver实现重现ObServer并将其重载其updat

IOS中UITabBar的常用设置

UITabBar十分常用,它能实现多个页面的快速切换,而且看起来简单实用. 假设我这有多个 已经初始化好的viewController,然后需要将它们加入到TabBarController中,并把其设置为根视图 NSArray *views = [[NSArray alloc] initWithObjects:test, time, test1, test2, test3, test4, nil]; UITabBarController *tbc = [[UITabBarController a

IOS 单例设计模式解读

IOS 中单例设计模式的解读与用法 一.单例的作用       顾名思义,单例,即是在整个项目中,这个类的对象只能被初始化一次.它的这种特性,可以广泛应用于某些需要全局共享的资源中,比如管理类,引擎类,也可以通过单例来实现传值.UIApplication.NSUserDefaults等都是IOS中的系统单例. 二.单例的写法        单例的写法常用的有两种方式:        方式1.不考虑线程 ? 1 2 3 4 5 6 7 8 static SingleCase *manager = 

ios-需要在IOS中设置延迟功能

问题描述 需要在IOS中设置延迟功能 需要一个延时器,进行23秒的延迟然后执行函数.应该怎么实现?用不用NSTimer? 解决方案 performSelector: withObject: afterDelay: 解决方案二: 简单点的话,使用performSelector: withObject: afterDelay: 方法 [self performSelector:@selector(delayMethod:) withObject:nil afterDelay:23];

error-请教iOS中CMPedometer的用法

问题描述 请教iOS中CMPedometer的用法 10C #import @implementation FirstViewController (void)viewDidLoad { [super viewDidLoad]; [CMPedometer isStepCountingAvailable]; CMPedometer *pedonmeter = [[CMPedometer alloc] init]; [pedonmeter startPedometerUpdatesFromDate:

IOS中KVC与KVO的应用解析

IOS中KVC与KVO的应用解析 一.NSKeyValueCoding(KVC) 1.从一个小例子引入 KVC键值编码是Object-C为我们提供的一种对成员变量赋值的方法.在探讨其方法之前,我们先来看一个小例子: 首先,创建一个数据模型model类: ? 1 2 3 4 5 6 7 8 //.h文件 #import <Foundation/Foundation.h> @interface Model : NSObject {     @public//将成员变量设置为公有的 以便其他文件有访

IOS中JSON数据的解析

IOS中JSON数据解析 官方为我们提供的解析JSON数据的类是NSJSONSerialization,首先我们先来看下这个类的几个方法: + (BOOL)isValidJSONObject:(id)obj; 判断一个数据对象是否可以转化为JSON数据 + (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error; 将JSON数据写为NSData数据,其中opt参数