黑马程序员技术交流社区

标题: [学习心得] 组合模式(Composite Pattern) [打印本页]

作者: 枫煠    时间: 2014-12-27 22:41
标题: [学习心得] 组合模式(Composite Pattern)
本帖最后由 枫煠 于 2014-12-27 22:47 编辑

最近在练习设计模式中的-组合模式,趁还印象深刻来发篇文章赚赚分好了....

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




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

  1. //FileComposite.h
  2. @interface FileComposite : NSObject
  3. @property(strong, nonatomic) NSString* file_name;
  4. @property(strong, nonatomic) NSString* file_size;
  5. @property(strong, nonatomic) NSDate*   modification_date;
  6. @property(assign, nonatomic) EntryType entry_type;
  7. @property(strong, nonatomic) NSString* file_path;

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

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

  10. -(NSArray*) subItems;
  11. @end

  12. @interface ComFile : FileComposite

  13. @end

  14. @interface ComDirectory : FileComposite

  15. @end
复制代码

  1. //FileComposite.m
  2. @implementation FileComposite

  3. -(FileComposite*) initWithPath:(NSString*)path{
  4.     self = [super init];
  5.     if (self) {
  6.         self.file_path = path;
  7.         self.file_name = [path lastPathComponent];
  8.         
  9.         NSString* full_path = [[[ComFilesBrowserMgr getInstance] getBaseURLString] stringByAppendingPathComponent:path];
  10.         self.attributesDic =[[NSFileManager defaultManager] attributesOfItemAtPath:full_path error:nil];
  11.         self.modification_date = [self.attributesDic fileModificationDate];
  12.     }
  13.     return self;
  14. }

  15. -(void) add:(FileComposite*)c{
  16. //不实作
  17. }

  18. -(NSArray*) subItems{
  19.     //不实作
  20.     return nil;
  21. }

  22. @end

  23. @implementation ComFile

  24. -(FileComposite*) initWithPath:(NSString*)path{
  25.     self = [super initWithPath:path];
  26.     if (self) {
  27.         self.entry_type = kEntryTypeGeneric;
  28.         
  29.         //将档案大小转换成文字KB、MB、GB之类的
  30.         long long fileSize = [self.attributesDic fileSize];
  31.         if (fileSize==0) {
  32.             self.file_size= @"0 KB";
  33.         }
  34.         else{
  35.             self.file_size=[NSByteCountFormatter stringFromByteCount:fileSize countStyle:NSByteCountFormatterCountStyleFile];
  36.         }
  37.     }
  38.     return self;
  39. }

  40. -(void) add:(FileComposite*)c{
  41.     //不实作
  42. }

  43. -(NSArray*) subItems{
  44.     //不实作
  45.     return nil;
  46. }
  47. @end

  48. @interface ComDirectory ()
  49. @property(strong, nonatomic) NSMutableArray* children;
  50. @end
  51. @implementation ComDirectory

  52. -(FileComposite*) initWithPath:(NSString*)path{
  53.     self = [super initWithPath:path];
  54.     if (self) {
  55.         self.entry_type = kEntryTypeDirectory;
  56.     }
  57.     return self;
  58. }

  59. -(NSMutableArray*) children{
  60.     if (!_children) {
  61.         _children = [@[]mutableCopy];
  62.     }
  63.     return _children;
  64. }

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

  69. -(NSArray*) subItems{
  70.     return self.children;
  71. }
  72. @end
复制代码

然后当需要一个找寻一个目录里面的内容时,就利用这种组合做出一个FileComposite出来
  1. ComDirectory* parentCom = [[ComDirectory alloc] initWithPath:relativePath];
  2.     for (NSString* path in contents){
  3.         NSString* source_path = [relativePath stringByAppendingPathComponent:path];
  4.         NSString* full_path = [self.rootPath stringByAppendingPathComponent:source_path];
  5.         if ([self isDirectoryAtURLString:full_path]){
  6.             //将directory加入parent里
  7.             ComDirectory* directory=[[ComDirectory alloc] initWithPath:source_path];
  8.             [parentCom add:directory];
  9.         }
  10.         else{
  11.             //将file加入parent里
  12.             ComFile* file=[[ComFile alloc] initWithPath:source_path];
  13.             [parentCom add:file];
  14.         }
  15.     }
  16. }
复制代码


得到FileComposite之后,只需要
  1. FileComposite* entry= [[ComFilesBrowserMgr getInstance] loadFilesListAtDir:self.currentPath];
  2.     NSArray* subItems =[entry subItems];
复制代码
sumItems就是指定目录底下的项目内容

最后附上小Demo,谢谢您的观赏~不嫌弃的话可以赏点分或是币,觉得写得不好的话麻烦鞭小力点^^
因为超过论坛上传附件的限制,把Demo分享到百度盘,有兴趣的可以自己去抓下来
链接: http://pan.baidu.com/s/1daP8i 密码: cppc

作者: dream_style    时间: 2014-12-28 00:02
赞赞赞赞赞赞。。。
作者: zhaozigeng    时间: 2014-12-28 11:16
谢谢了.学习一下.




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2