您好,欢迎来到年旅网。
搜索
您的当前位置:首页[DesignPattern] 组合 Composite

[DesignPattern] 组合 Composite

来源:年旅网

使用目的:

         让使用它的人认为它们是同一个类别的物件
例子:
         档案系统(树状图),如下图的UML所画的(图的来源是随便找的),File、Directory都是继承于Entry,
外面的人只需要操作Entry就能同时使用不同类别的物件,File与Directory针对各自的特性去实作它们的方法,

而不是Entry,不过若是共有属性,就可以直接在Entry里面实作

针对上图我简单做一个很简陋的档案浏览器Demo,来练习这种组合模式
首先我建立了FileComposite类别来当做上图的Etnry,
然后建立了ComFile、ComDirectory去继承FileComposite如下:

//FileComposite.h
@interface FileComposite : NSObject
@property(strong, nonatomic) NSString* file_name;
@property(strong, nonatomic) NSString* file_size;
@property(strong, nonatomic) NSDate*   modification_date;
@property(assign, nonatomic) EntryType entry_type;
@property(strong, nonatomic) NSString* file_path;

-(FileComposite*) initWithPath:(NSString*)path;

-(void) add:(FileComposite*)c;

-(NSArray*) subItems;
@end

@interface ComFile : FileComposite

@end

@interface ComDirectory : FileComposite

@end
//FileComposite.m
@implementation FileComposite

-(FileComposite*) initWithPath:(NSString*)path{
    self = [super init];
    if (self) {
        self.file_path = path;
        self.file_name = [path lastPathComponent];
        
        NSString* full_path = [[[ComFilesBrowserMgr getInstance] getBaseURLString] stringByAppendingPathComponent:path];
        self.attributesDic =[[NSFileManager defaultManager] attributesOfItemAtPath:full_path error:nil];
        self.modification_date = [self.attributesDic fileModificationDate];
    }
    return self;
}

-(void) add:(FileComposite*)c{
//不实作
}

-(NSArray*) subItems{
    //不实作
    return nil;
}

@end

@implementation ComFile

-(FileComposite*) initWithPath:(NSString*)path{
    self = [super initWithPath:path];
    if (self) {
        self.entry_type = kEntryTypeGeneric;
        
        //将档案大小转换成文字KB、MB、GB之类的
        long long fileSize = [self.attributesDic fileSize];
        if (fileSize==0) {
            self.file_size= @"0 KB";
        }
        else{
            self.file_size=[NSByteCountFormatter stringFromByteCount:fileSize countStyle:NSByteCountFormatterCountStyleFile];
        }
    }
    return self;
}

-(void) add:(FileComposite*)c{
    //不实作
}

-(NSArray*) subItems{
    //不实作
    return nil;
}
@end

@interface ComDirectory ()
@property(strong, nonatomic) NSMutableArray* children;
@end
@implementation ComDirectory

-(FileComposite*) initWithPath:(NSString*)path{
    self = [super initWithPath:path];
    if (self) {
        self.entry_type = kEntryTypeDirectory;
    }
    return self;
}

-(NSMutableArray*) children{
    if (!_children) {
        _children = [@[]mutableCopy];
    }
    return _children;
}

-(void) add:(FileComposite*)c{
    //加入子项目
    [self.children addObject:c];
}

-(NSArray*) subItems{
    return self.children;
}
@end

然后当需要一个找寻一个目录里面的内容时,就利用这种组合做出一个 FileComposite出来

ComDirectory* parentCom = [[ComDirectory alloc] initWithPath:relativePath];
    for (NSString* path in contents){
        NSString* source_path = [relativePath stringByAppendingPathComponent:path];
        NSString* full_path = [self.rootPath stringByAppendingPathComponent:source_path];
        if ([self isDirectoryAtURLString:full_path]){
            //将directory加入parent里
            ComDirectory* directory=[[ComDirectory alloc] initWithPath:source_path];
            [parentCom add:directory];
        }
        else{
            //将file加入parent里
            ComFile* file=[[ComFile alloc] initWithPath:source_path];
            [parentCom add:file];
        }
    }
}

得到FileComposite之後,只需要

FileComposite* entry= [[ComFilesBrowserMgr getInstance] loadFilesListAtDir:self.currentPath];
    NSArray* subItems =[entry subItems];

sumItems就是指定目录底下的项目内容

最后附上小Demo

https://github.com/joyce-328/CompositePattern.git


因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务