标签:
今天晚上跟大家主要来讨论下适配器模式和多态,什么是适配器模式呢?先抛给大家一个问题:假设两个类Student和Teacher继承一个抽象基类Person,如何在不改动三类情况下实现多Student、Teacher功能的扩展?我们看下图
假设我们现在要对Student和Teacher两个类增加一个showType()的方法并不改动上图的三个类,我们应该怎么办呢?先思考一下,再往下看。
我们回到开头的问题,什么是适配器模式?百度百科的飞机票:点我进入
通俗来说,适配器一般适用于在不该改变原有结构上进行扩展新功能。比如说一些功能已经无法满足我们现在的需求,但是我们又不能对以前的系统进行修改,那么这个时候我们就可以通过适配器模式进行实现。我们看下加了适配器后,上图会变成什么样子呢?
从上图我们可以看到,我们定义了IPersonAdapterable接口并为其添加了一个PersonAdapter实现类,我们在项目中如果要用到的新的功能的话我们可以在PersonAdapter类中进行添加。下面贴上实例代码:
1 using System; 2 namespace 大壮他哥博客园 3 { 4 class Program 5 { 6 7 static void Main(string[] args) 8 { 9 var student = new Student(); 10 var personAdapterable = new PersonAdapterable(student); 11 personAdapterable.ShowType(); 12 Console.ReadLine(); 13 } 14 } 15 16 public class Person { } 17 public class Teacher : Person { } 18 public class Student : Person { } 19 20 public interface IPersonAdapterable 21 { 22 void ShowType(); 23 } 24 25 public class PersonAdapterable : IPersonAdapterable 26 { 27 28 private Person _person; 29 public PersonAdapterable(Person person) 30 { 31 this._person = person; 32 } 33 34 public void ShowType() 35 { 36 if (_person is Student) 37 { 38 Console.WriteLine("我是Student类"); 39 } 40 else if (_person is Teacher) 41 { 42 Console.WriteLine("我是Teacher类"); 43 } 44 45 //略,这里可以根据具体的类型实现对应的操作 46 47 } 48 49 } 50 }
看了上面的例子相信大家已经对适配器模式有了一定的了解。那么什么是多态呢?多态可以简单的定义为:呈现不同的形式或者能力。举个栗子,我女朋友要吃面,需要我去帮她买,但是她并没有告诉我她要吃什么面,我有可能给她买大武汉的热干面或者兰州拉面。在这个例子中,我女朋友是不去管我给她买什么面的,只要是面她就愿意吃。但是,如果我去买了个馒头,那我肯定就要跪搓衣板了。。
可能上面的例子不够形象,下面我引用《你必须知道.NET》书中的一个万能加载器的例子。先来说下“万能加载器”的需求:
1:能够打开常见的文档类资料,如:TXT/WORD/PDF等
2:能够打开常见的图片资料,如:JPG/GIF/PNG等
3:能够打开常见的音频资料,如:MP3/MP4/AVI等
4:支持简单可用的类型扩展接口,易于实现更多文件类型的加载。
拿到需求后,我们第一反应是,OK,这么简单的功能,分分钟实现,于是你就有了以下的基本框架:
我们首先定义了一个文件类型枚举:
public enum FileType { doc, pdf, txt, ppt, jpg, gif, mp3, avi }
有了支持的文件类型,我们首先想到的是创建一个文件类,来代表不同的文件类型:
public class Files { private FileType _fileType; public FileType FileType => _fileType; public Files(FileType filetype) { this._fileType = filetype; } }
我们创建了一个FileManager类,用来封装不同的文件不同的打开方式:
1 public class FileManager { 2 3 public void OpenDoc() { 4 5 Console.WriteLine("OpenDoc"); 6 } 7 8 9 public void OpenMp3() { 10 Console.WriteLine("OpenDoc"); 11 } 12 13 //略 14 }
我们在Main方法调用方式如下:
static void Main(string[] args) { IList files = new List<Files>(); var fileManager = new FileManager(); foreach (Files item in files) { switch (item.FileType) { case FileType.doc: fileManager.OpenDoc(); break; case FileType.mp3: fileManager.OpenMp3(); break; //略下N多分支 } } Console.ReadLine(); }
暂时这个万能加载器算是完成了,但是假如说现在忽然要支持一种以前从未支持的格式的时候,想想我们的系统要怎么去应对?首先,我们要去增加FileType枚举中的文件类型,然后在FileManager增加一个打开的方法,然后在调用的地方增加分支。。。一个两个可能觉得还好,想想,如果几十几百个呢。。。想想就要疯掉。。。。。我们可以简化吗??为什么不呢?这个时候,多态就是我们救命稻草,来看看利用多态我们怎么处理。
先整理下思路,无论是doc还是pdf或者说是MP3,它们都属于文件,我们可以先把他们进行抽象,然后在每个类内部对文件进行打开的操作。
没有抽象化之前的
抽象之后的
大家可以看到,我们把文件单独提成一个File类,然后所有的文件处理类去继承于File类,这样的话如果后期要增加一个新的文件类型,我们只需要添加一个类继承File就可以了,如图所示PDFFile文件类,那么经过这样的修改后,Main方法调用有什么改变呢?
IList files = new List<File>(); foreach (File item in files) { item.open(); } Console.ReadLine();
之前的代码里面我们需要对每个item进行判断然后调用相应的方法,为什么经过修改后就不用去判断呢?因为在向files集合添加对象的时候,对象值一定是File类的某个子类,Files里面每个对象就相当于一种文件类型了,所以我们不用判断,直接调用对象的Open方法就可以了。。。
标签:
原文地址:http://www.cnblogs.com/dazhuangtage/p/5724367.html