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.

最新文章

  1. Organization SYMMETRIC MULTIPROCESSORS
  2. 设计模式之 面向对象的养猪厂的故事,C#演示(二)
  3. ArrayList与LinkedList区别
  4. WPF界面按钮美化
  5. 关于sbutils中的sblaunch插件的疑惑
  6. ubuntu12.04.5安装openssh-server所引发的血案
  7. python标准库]Hashlib
  8. class not found: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  9. 13.MySQL(一)
  10. 在VS2017中安装OpenGL
  11. 部署 Helm - 每天5分钟玩转 Docker 容器技术(162)
  12. Redis常用数据类型和事物以及并发
  13. Java 8 特性 —— lambda 表达式
  14. 浏览器URL中 encodeURIComponent()加密和decodeURIComponent()解码
  15. HDU 1541 STAR(树状数组)
  16. 【PMP】组织结构类型
  17. winform 子窗体调用父窗体中的方法
  18. TypeScript开发环境搭建(Visual studio code)
  19. 操作系统:Android(Google公司开发的操作系统)
  20. jmeditor与CKEditor4x整合的BUG

热门文章

  1. 洛谷 P3803 多项式乘法(FFT) —— FFT
  2. xen添加网卡
  3. GetModuleFileNameW
  4. vs未能正确加载XX包的解决方法
  5. KNN分类算法--python实现
  6. Manasa and Combinatorics
  7. Codeforces 1108F MST Unification MST + LCA
  8. Flutter实战视频-移动电商-37.路由_Fluro引入和商品详细页建立
  9. Makefile研究 (一)—— 必备语法
  10. Server.MapPath()相关