响应式网站建设外文文献,网站开发中期检查,ppt设计网站,企业网站如何建设和推广迭代器模式和组合模式混用 前言 园子里说设计模式的文章算得上是海量了#xff0c;所以本篇文章所用到的迭代器设计模式和组合模式不提供原理解析#xff0c;有兴趣的朋友可以到一些前辈的设计模式文章上学学#xff0c;很多很有意思的。在Head First 设计模式这本书中… 迭代器模式和组合模式混用 前言 园子里说设计模式的文章算得上是海量了所以本篇文章所用到的迭代器设计模式和组合模式不提供原理解析有兴趣的朋友可以到一些前辈的设计模式文章上学学很多很有意思的。在Head First 设计模式这本书中也有说迭代和组合模式混用的方法但是使用的语言是JAVA实现起来比起C#差异还是不少。本人在做几个C#小项目的时候需要用到树形结构也看到了Head First 设计模式中混用迭代器和组合模式的例子觉得如果能用C#实现以后无疑会带来很大的帮助。下面就记录下实现过程希望有不好的地方各位前辈大力拍晚生会努力改正本文使用C#。 效果与目标 1.能自动遍历树形结构中的所有节点。 2.对树中所有节点进行统一管理统一到一个根节点上。 举个例子文件系统有文件夹和文件这两个类型形成一个文件系统树形结构使用了本文章所说的混用模式以后能轻松对每一个结点进行自动处理最简单的就是打印各自的名字和子文件系统或排序等。 实现过程 下面以文件系统为例可以根据需要灵活改变主要讲得是思想而已。 新建一个C#控制台随便改个名字。 搭建类和接口实现组合模式。 1.IFileSystemNode文件系统接口 interface IFileSystemNode{String Name { set; get; }String Path { set; get; }ListIFileSystemNode Children { set; get; }IEnumerator getIterator();void ShowName();} View Code 2.FolderNode文件夹节点类 class FolderNode : IFileSystemNode{public FolderNode(String name, String path){this.Name name;this.Path path;}private string _name;public string Name{get{return _name;}set{_name value;}}private string _path;public string Path{get{return _path;}set{_path value;}}private ListIFileSystemNode _children new ListIFileSystemNode();public ListIFileSystemNode Children{get{return _children;}set{_children value;}}public void ShowName(){Console.WriteLine(Name);}public System.Collections.IEnumerator getIterator(){throw new NotImplementedException();}} View Code 3.FileNode文件节点类 class FileNode : IFileSystemNode{public FileNode(String name, String path){this.Name name;this.Path path;}private string _name;public string Name{get{return _name;}set{_name value;}}private string _path;public string Path{get{return _path;}set{_path value;}}public ListIFileSystemNode Children{get{throw new NotImplementedException();}set{throw new NotImplementedException();}}public void ShowName(){Console.WriteLine(Name);}public System.Collections.IEnumerator getIterator(){throw new NotImplementedException();}} View Code 注意以上实现了组合模式其中getIterator方法是还没有代码的这个需要使用迭代器模式。 编写迭代器实现迭代器模式。 在FolderNode中有子节点但是在FileNode中没有子节点但是因为使用了组合器模式对于FolderNode和FileNode都需要实现相同的契(IFileSystemNode)。所以在FolderNode中返回的迭代器是用来迭代子节点而FileNode则不同它根本没有子节点那么就使用一个叫做空迭代器来满足契约。 下面分别实现具体迭代器继承C#系统提供的IEnumerator接口。 1.为FolderNode提供具体迭代器FolderNodeIterator class FolderNodeIterator : IEnumerator{private IEnumerableIFileSystemNode fileSystems { set; get; }public FolderNodeIterator(IEnumerableIFileSystemNode _fileSystems){this.fileSystems _fileSystems;}private int currentIndex -1;public object Current{get { return fileSystems.ElementAt(currentIndex); }}public bool MoveNext(){if (currentIndex fileSystems.Count() - 1){currentIndex;return true;}return false;}public void Reset(){currentIndex -1;}} View Code 新建完类以后我们修改下FolderNode类中的getIterator方法返回一个FolderNodeIterator实例,代码如下 public IEnumerator getIterator(){return new FolderNodeIterator(_children);} 2.为FileNode提供具体迭代器EmptyIterator class EmptyIterator : IEnumerator{public object Current{get { return null; }}public bool MoveNext(){return false;}public void Reset(){}} View Code 新建完类以后我们同样修改下FileNode类中的getIterator方法返回一个EmptyIterator实例代码如下 public IEnumerator getIterator(){return new EmptyIterator();} 使用 好像差不多了我们使用使用一下这个模型 为了添加真实性本演示映射了真实文件系统请在Programe类上添加一个静态方法Convert private static void Convert(FolderNode root, String directoryPath){foreach (var filesystempath in Directory.EnumerateFiles(directoryPath)){if (root.Children ! null){root.Children.Add(new FileNode(Path.GetFileName(filesystempath), filesystempath));}}foreach (var filesystempath in Directory.EnumerateDirectories(directoryPath)){FolderNode newFolderNode new FolderNode(Path.GetFileName(filesystempath), filesystempath);root.Children.Add(newFolderNode);Convert(newFolderNode, filesystempath);}} View Code 然后我们在Main方法中就能先映射再使用来看一下Main方法其中使用了迭代器模式去迭代各个子项 static void Main(string[] args){FolderNode root new FolderNode(酷狗音乐, C:\Users\Administrator\Desktop\\酷狗音乐);Convert(root, C:\Users\Administrator\Desktop\\酷狗音乐);IEnumerator Myiterator root.getIterator();while (Myiterator.MoveNext()){IFileSystemNode ctextIterator (IFileSystemNode)Myiterator.Current;ctextIterator.ShowName();}Console.ReadKey();} 我映射了桌面上的一个文件看看文件结构 有一个hozin文件夹(里面有3首歌)一个Ltheme文件夹(里面有一首歌),一个文件(08开头的歌)。 好了运行程序看看结果,好像有点问题为什么只有一个层的呢也就是说为什么只迭代了root节点的一层子节点子节点的子节点还没有遍历完这是因为FolderNodeIterator的迭代只提供了一层迭代而不会深层迭代。所以如果想要深层迭代使用Head First设计模式中的思想就是提供一个组合迭代器用来包装FolderNodeIterator提供深层迭代功能。下面是我在C#中的实现代码,添加这样一个类CompositeIterator class CompositeIterator : IEnumerator{public CompositeIterator(IEnumerator ienumerator){temp.Push(ienumerator);root ienumerator;}IEnumerator root;StackIEnumerator temp new StackIEnumerator();private IFileSystemNode _current;public object Current{get { return _current; }}public bool MoveNext(){if (temp.Count 0){return false;}if (temp.Peek().MoveNext()){_current temp.Peek().Current as IFileSystemNode;IEnumerator ienumerator _current.getIterator();if (ienumerator.MoveNext()){ienumerator.Reset();temp.Push(ienumerator);}}else{temp.Pop();MoveNext();}if (temp.Count 0){return false;}else{return true;}}public void Reset(){temp.Clear();temp.Push(root);}} View Code 然后修改FolderNode类中的getIterator方法如下 public System.Collections.IEnumerator getIterator(){return new CompositeIterator(new FolderNodeIterator(this._children));} 包装完以后再次运行。OK大功告成 总结 为了适应真实项目可以改的点有很多 1.这里只有FolderNode和FileNode在实际项目中可能不止可以添加只要继承同一个接口这里是IFileSystemNode那么就能像皇帝发号命令一样命令所有子子孙孙做事情了(在root节点上调用IFileSystemNode上声明有的方法)。 2.添加契约方法例如像要对每一个节点进行排序Sort,直接添加一个方法然后子孙各自实现方法最后调用root节点的Sort。 3.这里的遍历使用前序遍历遍历树的所有节点但是也可以使用您喜欢的方式只要修改组合迭代器。 源码下载 转载于:https://www.cnblogs.com/Jarvin/p/3735460.html