We can create subclass within a class cluster that defines a class that embeds within it an object. These class objects are composite objects.

So you might be wondering what's a class cluster. So we will first see what's a class cluster.

Class Clusters

Class clusters are a design pattern that the Foundation framework makes extensive use of. Class clusters group a number of private concrete subclasses under a public abstract superclass. The grouping of classes in this way simplifies the publicly visible architecture of an object-oriented framework without reducing its functional richness. Class clusters are based on the Abstract Factory design pattern.

To make it simple, instead of creating multiple classes for similar functions, we create a single class that will take care of its handling based on the value of input.

For example, in NSNumber we have many clusters of classes like char, int, bool and so on. We group all of them to a single class that takes care of handling the similar operations in a single class. NSNumber actually wraps the value of these primitive types into objects.

So what's exactly composite object?

By embedding a private cluster object in an object of our own design, we create a composite object. This composite object can rely on the cluster object for its basic functionality, only intercepting messages that the composite object wants to handle in some particular way. This architecture reduces the amount of code we must write and lets you take advantage of the tested code provided by the Foundation Framework.

This is explained in the following figure.

The composite object must declare itself to be a subclass of the cluster's abstract superclass. As a subclass, it must override the superclass' primitive methods. It can also override derived methods, but this isn't necessary because the derived methods work through the primitive ones.

The count method of the NSArray class is an example; the intervening object's implementation of a method it overrides can be as simple as:

- (unsigned)count
{
return [embeddedObject count];
}

In the above example, embedded object is actually of type NSArray.

A Composite Object example

Now in order to see a complete example, let's look at the example from the Apple documentation which is given below.

#import <Foundation/Foundation.h>

@interface ValidatingArray : NSMutableArray
{
NSMutableArray *embeddedArray;
} + validatingArray;
- init;
- (unsigned)count;
- objectAtIndex:(unsigned)index;
- (void)addObject:object;
- (void)replaceObjectAtIndex:(unsigned)index withObject:object;
- (void)removeLastObject;
- (void)insertObject:object atIndex:(unsigned)index;
- (void)removeObjectAtIndex:(unsigned)index; @end @implementation ValidatingArray
- init
{
self = [super init];
if (self) {
embeddedArray = [[NSMutableArray allocWithZone:[self zone]] init];
}
return self;
} + validatingArray
{
return [[self alloc] init] ;
}
- (unsigned)count
{
return [embeddedArray count];
}
- objectAtIndex:(unsigned)index
{
return [embeddedArray objectAtIndex:index];
}
- (void)addObject:(id)object
{
if (object != nil) {
[embeddedArray addObject:object];
}
}
- (void)replaceObjectAtIndex:(unsigned)index withObject:(id)object;
{
if (index <[embeddedArray count] && object != nil) {
[embeddedArray replaceObjectAtIndex:index withObject:object];
}
}
- (void)removeLastObject;
{
if ([embeddedArray count] > ) {
[embeddedArray removeLastObject];
}
}
- (void)insertObject:(id)object atIndex:(unsigned)index;
{
if (object != nil) {
[embeddedArray insertObject:object atIndex:index];
}
}
- (void)removeObjectAtIndex:(unsigned)index;
{
if (index <[embeddedArray count]) {
[embeddedArray removeObjectAtIndex:index];
}
} @end int main()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
ValidatingArray *validatingArray = [ValidatingArray validatingArray];
[validatingArray addObject:@"Object1"];
[validatingArray addObject:@"Object2"];
[validatingArray addObject:[NSNull null]];
[validatingArray removeObjectAtIndex:];
NSString *aString = [validatingArray objectAtIndex:];
NSLog(@"The value at Index 1 is %@",aString);
[pool drain];
return ;
}

Now when we compile and run the program, we will get the following result.

-- ::54.294 demo[] The value at Index  is Object2

In the above example, we can see that validating array's one function would not allow adding null objects that will lead to crash in the normal scenario. But our validating array takes care of it. Similarly, each of the method in validating array adds validating processes apart from the normal sequence of operations.

Objective-C Composite Objects的更多相关文章

  1. Composite Design Pattern in Java--转

    https://dzone.com/articles/composite-design-pattern-in-java-1 The composite pattern is meant to &quo ...

  2. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  3. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  4. linux内核的makefile.txt讲解

    linux内核的linux-3.6.5\Documentation\kbuild\makefiles.txt Linux Kernel Makefiles This document describe ...

  5. Linux内核Makefile文件(翻译自内核手册)

    --译自Linux3.9.5 Kernel Makefiles(内核目录documention/kbuild/makefiles.txt) kbuild(kernel build) 内核编译器 Thi ...

  6. SOLID architecture principles using simple C# examples

    转:http://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp?msg=4 ...

  7. CG&Game资源(转)

    cg教程下载: http://cgpeers.com http://cgpersia.com http://bbs.ideasr.com/forum-328-1.html http://bbs.ide ...

  8. Kbuild文件

    3 Kbuild文件 大部分内核中的Makefile都是使用Kbuild组织结构的Kbuild Makefile.这章将介绍Kbuild Makefile的语法. 对于Kbuild文件名来讲,Kbui ...

  9. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

随机推荐

  1. JAVA 需要理解的重点 一

    需要理解的重点内容有: JVM内存管理机制和垃圾回收机制(基本每次面试都会问,一定要搞得透彻) JVM内存调优(了解是怎么回事,一般做项目过程中使用较多) 设计模式(熟悉常见设计模式的应用场景,会画类 ...

  2. redis sentinel(哨兵)配置解读

    1 port <sentinel-port> :哨兵实例运行所在的端口(默认26379) 2 sentinel announce-ip:哨兵将会在gossip hello消息中使用指定的i ...

  3. 5.js屏蔽方向键,兼容IE和firefox

    document.onkeydown=function(e){ e=e||event; //屏蔽向左的方向键 if(e.keyCode==37){ alert('禁止向左的方向键!'); return ...

  4. 1.oracle中decode的一些巧妙用法

    1.符号函数sign在decode中的用法--比较大小 select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值sign()函数根据某个值是0 ...

  5. Even Three is Odd

    题意: 问题是对于所有的长度为n,且$1<=ai<=n$的整数序列求 $\prod_{i=1}^{n-2}{max \{w_i,w_{i+1},w_{i+2}}\}$ 之和. 解法: 首先 ...

  6. CodeForces 1098E. Fedya the Potter

    题目简述:给定长度为$n \leq 5\times 10^4$的序列$a_1, a_2, \dots, a_n \leq 10^5$.将$\gcd(a_l, a_{l+1}, \dots, a_r) ...

  7. TypeScript完全解读(26课时)_20.声明文件

    首先学习识别已有的js库的类型 识别已有的js库的类型 UMD既可以作为全局库使用,也可以作为模块使用 先在着手来编写一个全局的库 新建文件 接收一个title,改变页面title的值 这里用到 &a ...

  8. Laravel框架之Request操作

    public function request(Request $request){ //1.取值 //echo $request->input('name'); //echo $request ...

  9. python 三元表达式 列表推导式,生成器表达式。递归,匿名函数, 内置函数

    三元表达式 三元表达式仅应用于: 1.条件成立返回一个值 2.条件不成立返回一个值 res = x if x>y else y print(res) name= input("姓名&g ...

  10. django使用QQ企业邮箱发送邮件

    一.首先申请QQ企业邮箱 免费QQ企业邮箱地址如下:https://exmail.qq.com/signupfree?refer=intro#signup/free 二.配置自己的域名 在域名解析中添 ...