今天晚上跟大家主要来讨论下适配器模式和多态,什么是适配器模式呢?先抛给大家一个问题:假设两个类Student和Teacher继承一个抽象基类Person,如何在不改动三类情况下实现多Student、Teacher功能的扩展?我们看下图

  假设我们现在要对Student和Teacher两个类增加一个showType()的方法并不改动上图的三个类,我们应该怎么办呢?先思考一下,再往下看。

  我们回到开头的问题,什么是适配器模式?百度百科的飞机票:点我进入

  通俗来说,适配器一般适用于在不该改变原有结构上进行扩展新功能。比如说一些功能已经无法满足我们现在的需求,但是我们又不能对以前的系统进行修改,那么这个时候我们就可以通过适配器模式进行实现。我们看下加了适配器后,上图会变成什么样子呢?

  从上图我们可以看到,我们定义了IPersonAdapterable接口并为其添加了一个PersonAdapter实现类,我们在项目中如果要用到的新的功能的话我们可以在PersonAdapter类中进行添加。下面贴上实例代码:

 using System;
 namespace 大壮他哥博客园
 {
     class Program
     {

         static void Main(string[] args)
         {
             var student = new Student();
             var personAdapterable = new PersonAdapterable(student);
             personAdapterable.ShowType();
             Console.ReadLine();
         }
     }

     public class Person { }
     public class Teacher : Person { }
     public class Student : Person { }

     public interface IPersonAdapterable
     {
         void ShowType();
     }

     public class PersonAdapterable : IPersonAdapterable
     {

         private Person _person;
         public PersonAdapterable(Person person)
         {
             this._person = person;
         }

         public void ShowType()
         {
             if (_person is Student)
             {
                 Console.WriteLine("我是Student类");
             }
             else if (_person is Teacher)
             {
                 Console.WriteLine("我是Teacher类");
             }

             //略,这里可以根据具体的类型实现对应的操作

         }

     }
 }

    看了上面的例子相信大家已经对适配器模式有了一定的了解。那么什么是多态呢?多态可以简单的定义为:呈现不同的形式或者能力。举个栗子,我女朋友要吃面,需要我去帮她买,但是她并没有告诉我她要吃什么面,我有可能给她买大武汉的热干面或者兰州拉面。在这个例子中,我女朋友是不去管我给她买什么面的,只要是面她就愿意吃。但是,如果我去买了个馒头,那我肯定就要跪搓衣板了。。

    可能上面的例子不够形象,下面我引用《你必须知道.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类,用来封装不同的文件不同的打开方式:

  public class FileManager {

         public void OpenDoc() {

             Console.WriteLine("OpenDoc");
         }

         public void OpenMp3() {
             Console.WriteLine("OpenDoc");
         }

         //略
     }

    我们在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)与多态的更多相关文章

  1. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

  2. 【设计模式】适配器模式 Adapter Pattern

    适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...

  3. Java基础拾遗(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76358523冷血之心的博客) 马上就要秋招了,新的一轮笔试面试马上 ...

  4. Java基础拾遗(一)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76358391冷血之心的博客) 马上就要秋招了,新的一轮笔试面试马上 ...

  5. 基础拾遗------redis详解

    基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...

  6. 基础拾遗------webservice详解

    基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...

  7. [.net 面向对象编程基础] (13) 面向对象三大特性——多态

    [.net 面向对象编程基础] (13) 面向对象三大特性——多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...

  8. 二十四种设计模式:适配器模式(Adapter Pattern)

    适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...

  9. 设计模式 - 适配器模式(adapter pattern) 具体解释

    适配器模式(adapter pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 适配器模式(adapter pattern): 将一个类的接 ...

随机推荐

  1. 阻止系统自动睡眠的小软件,附C#制作过程

    原文 http://www.cnblogs.com/h46incon/p/SleepPreventer.html 因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环 ...

  2. Struts2 中action之间的跳转(分享)

    例如从你的login.action到register.action  有两种实现方式 1. 设置type="redirect" <package  name="st ...

  3. 17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment 引入额外的Slaves 到一个存在的复制

    17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment 引入额外的Slaves 到一个存在的复制环境 ...

  4. js正则表达式验证字符长度

    原理,就是把一个汉字替换为两个字母,来实现长度验证. //js正则验证字符长度 第一种:直接输出长度 alert('1sS#符'.replace(/[^\x00-\xff]/g, 'AA').leng ...

  5. 简简单单C#爬虫小计

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

  6. centos主机建立ssh互信

    ssh-keygen 生成密钥 1.ssh-keygen -t rsa 可以加密和签名 rsa 只能加密不能签名 2.ssh-copy-id -i /root/.ssh/id_rsa.pub USER ...

  7. C语言回溯算法解决N皇后问题

    回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...

  8. python优秀库 - 使用xmltodict解析xml文档

    上次讲到如何使用BeautifulSoup解析XML文档,今天发现另外一个python库xmltodict(https://github.com/martinblech/xmltodict)也很简单. ...

  9. Shell Script(1)----variable compare

    PS:在学习python的时间里,抽空复习自己学习的Linux下的shell脚本知识点 1.数据类型 学习一门语言,比较关心其数据的表示方式,以及数据的类型,这里首先看一个bash shell的脚本 ...

  10. 转: ajax跨域之JSONP

    事件背景: 某个站点分为静态产品介绍页面(或由于某原因需要静态化),和一个独立的在线应用程序.静态产品页面属于www.a.com下,而在线应用程序作为一个相对独立的系统存在于app.a.com上. 在 ...