码迷,mamicode.com
首页 > Web开发 > 详细

【.Net基础拾遗】适配器模式(Adapter)与多态

时间:2016-08-01 01:46:20      阅读:453      评论:0      收藏:0      [点我收藏+]

标签:

  今天晚上跟大家主要来讨论下适配器模式和多态,什么是适配器模式呢?先抛给大家一个问题:假设两个类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方法就可以了。。。

【.Net基础拾遗】适配器模式(Adapter)与多态

标签:

原文地址:http://www.cnblogs.com/dazhuangtage/p/5724367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!