多态的艺术—小兵笔记(1)
http://blog.csdn.net/wo13548581625/article/details/7858047 由于代码打不开,请看我的CSDN博客谢谢
应用场景
小兵的爷爷,开始着迷于电脑这个新玩意儿,但是老人家面对陌生的屏幕却总是摸不着头脑,各种各样的文件和资料烟花缭乱,老人家不知道如何打开,这可急坏了身为光荣程序员的小兵。为了让爷爷享受高科技带来的便捷与震撼,小兵决定自己开发一个万能程序,用来一键式打开常见的计算机资料,例如文档,图片和影响文件等,只需要安装一个程序就可以免了其他应用文件的管理,并且使用方便,就暂且称之为万能加载器(FileLoader).
功能分析:
l 自动加载各种资料,一站式搜索系统常见资料。
l 能够打开常见文的档类资料,例如txt文件,Word文件,PDF文件,Visio文件等。
l 能够打开常见的图片资料,例如jpg格式文件,gif格式文件,png格式文件。
l 能够打开常见音频资料和视频资料,例如avi文件,mp3文件等。
面向过程的设计来实现该功能
最初实现
文件类型
View Code
文件类
View Code
文件管理类
View Code
客户端程序
View Code
完成了文件打开的客户端,万能文档器已经有了基本的架子,现在小兵那个爷爷试手,发现爷爷正在打开一段rm格式的京剧听听。但是小王的系统还没有这一格式的支持,只好回去对原有系统进行重构。
等到添加新类型的时候,拿着半成品的小兵,突然发现自己的系统好像很难在插进一脚,除了添加新的类型,还需修改打开文件的操作代码,还得在管理类中添加新的支持代码,最后在客户端还要修改相应的操作。小兵发现添加新的类型,好像把原来的系统进行了一次大的装修,那下一次如果有新的需求,号称万能加载器产品,如何应对新的需求的变化呢?经过小兵的深入的分析发现了当前设计的几个重要的问题:
l Word,PDF,MP3等,都是可以实现的独立对象,整个系统除了有文档管理类,几乎没有面向对象的影子,全部是面向结构和过程的开发方式。
l 在实现打开程序时,小王发现其实OpenDocFile方法,OpenPDFFile方法以及OpenTxtFile方法有很多可复用的代码,而OpenJpgFile方法和OpenGifFile方法有很多的可重构的地方。
l 任何修改都会将整个系统洗礼一次,修改遍布全系统的整个代码,并且重新编译才行。
l 需求变更是结构化设计的大敌,无法轻松的完成起码的系统扩展和变更,例如在打开这一操作之外,如果实现删除和重命名等操作,对系统使一次重大的打击,在需求多变的今天,必须实现能够灵活多变的简单变更的设计构思,面向对象是灵活设计的有效手段之一。
小兵对新系统进行了重构
图1-2万能加载器框架设计调整
结合新的框架,比较之前的设计,小兵提出了新系统的新方案,主要进行了一下修改:
l 将word,pdf,txt,jpg,avi等业务实体抽象为对象,并且在每个相对应的对象内部来处理本对象类型的文件打开工作,这样各个类型之间的交互操作就会被分离出来,这样很好的体现了单一职责原则的目标。
l 将各个对象的属性和行为相分离,将文件打开这一行为封装为接口,在由其他类来实现这一接口,有利于系统的扩展同时减少了类与类之间的依赖。
l 将相似的类抽象为公共基类,在基类中实现具有共同特征,并由子类继承父类的特征,例如Word,PDF,TXT的基类可以抽象为DocFile;而JPG和GIF的基类可以抽象为ImageFile,这种实现体现的是面向对象的开放封闭原则;对扩展开发放,对修改关闭。如果有新的类型需要扩展,则只需要继承合适的基类成员,实现新类型的特征代码即可。
l 实现可柔性扩展接口机制,能够更加简单的实现添加新的文件类型加载程序,也能很好的扩展打开文件之外的其他操作,例如删除,重命名等修改操作。
l 实现在不需要调整原系统,或者减少调整原系统的情况下,进行功能扩展和优化,甚至是无须编译的插件式系统。
通用接口的定义:
FileType
文件类型枚举IFileOpen
定义所有文件类型的公共基类,因为文件基类不可被实例化,在此定义为抽象类更好。
Files
基类Fils实现IFileOpen接口,不过在此仍然定义为抽象方法。还可以实现其他的通用性的文件操作,比如:文件上传,文件删除,文件重命名等。
有了文件类型的公共基类,我们就可以实现其派生类了,小兵很聪明,把派生类进行归档,初步实现文件类型,图片类型,媒体类型三个大类别,将具体文件类型进行了抽象:
ImageFiles
具体实现:小兵现在要实现打开word文件操作,跟之前的设计对比,现在每个文件多有自己的Open规则。
WORDFile
我们现在来对比我们现在设计的文档管理器和之前文档管理器的设计:
LoadManager
客户端加载代码:
InsideConsole
当然这个框架的设计还有可以优化的地方,比如可以文件加载类型可以通过反射动态获取,避免耦合在客户端。
----《你必须知道的.Net》
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace InsideLibary.FileLoaderObj
7 {
8 public interface IFileOpen
9 {
10 void Open();
11 }
12
2 FileManager fileObj = new FileManager();
3
4 Files files = new Files();
5
6
7 // 文件资料集合
8 List<Files> ListFile = new List<Files>();
9 ListFile.Add(files);
10
11 // 打开电脑文件
12 foreach (Files file in ListFile)
13 {
14
15 switch (file.FileType)
16 {
17 case InsideLibary.FileType.doc:
18 fileObj.OpenDocFile();
19 break;
20 case InsideLibary.FileType.mp3:
21 fileObj.OpenMp3File();
22 break;
23 case InsideLibary.FileType.jpg:
24 fileObj.OpenJpgFile();
25 break;
26
27 // 省略代码
28 }
29
30