用事例说明多态

多态

书接上回,继续探究。
颠覆之前的构思。势在必行。
1、Word,pdf,mp3,txt,avi等将这些业务实体抽象为对象,并在每个对象内部来处理该文件的打开,这样各个类型之间的交互操作就被分离出来,这样很好的体现了职责单一的原则。
2、将对象的属性与行为相分离,将文件打开这一行为封装为接口,再有其他类来实现这一接口,利于系统的扩展减少类与类之间的依赖。
将相似的类抽象出公共基类,在基类中实现具有共性的特征,并有子类继承父类的特征。文档的基类可以抽象为DocLoader;图片格式的基类抽象为ImageLoader。这种方式体现了面向对象的开放关闭原则:对扩展开放,对修改关闭。

namespace Polymorphisn
{
    /// <summary>
    /// 通用接口定义
    /// </summary>
    internal interface IFileOpen
    {
        void Open();
    }
}

定义所有文件的公共基类

namespace Polymorphisn
{
    /// <summary>
    /// 所有文件的基类
    /// </summary>
    abstract class Files : IFileOpen
    {
        private FileType fileType = FileType.doc;
        public FileType FileType { get { return fileType; } }
        /// <summary>
        /// 抽象方法,除了文件打开抽象方法,还可以实现其他通用文件处理操作。
        /// </summary>
        public abstract void Open(); 
        //实现了IFileOpen接口
    }
}

有了文件类型的公共基类,是时候实现其派生类了

/// Doc文件
 abstract class DocFile : Files

 {
     /// <summary>
     /// 计算页数
     /// </summary>
     /// <returns></returns>
     public int GetPageCount() { return 0; }

 }
 /// 图片文件
abstract class ImageFile : Files
{
    public void ZommIn()
    {
        //放大比例
    }

    public void ZommOut()
    {
        //缩小比例
    }
}

终于是实现具体资料类的时候了,在此以 Word 类型为例来说明具体的实现:

class WORDFile : DocFile
{
    /// <summary>
    /// 打开Doc文件
    /// </summary>

    public override void Open()
    {
        Console.WriteLine("Open the Word file.");
    }
    //其他类型的实现类似于此,不同之处在于不同的类型有不同 Open 实现规则,
    //以应对不同资料的打开操作
}

class PDFFile : DocFile
{
    public override void Open()
    {
        Console.WriteLine("Open the PDF file.");
    }
}

同时提供了一个资料管理类来进行资料的统一管理:

internal class LoadManager
{
    private IList<Files> files = new List<Files>();
    public IList<Files> Files { get { return files; } }
    public void LoadFiles(Files file)
    {
        files.Add(file);

    }
    /// <summary>
    /// 打开所有文件资料
    /// </summary>
    public void OpenAllFiles()
    {
        foreach (var file in files)
        {
            file.Open();
        }
    }

    /// <summary>
    /// 打开单个文件资料
    /// </summary>
    /// <param name="file"></param>
    public void OpenFile (IFileOpen file)
    {
        file.Open();
    }

    /// <summary>
    /// 获取文件类型
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public FileType GetFileType(string fileName)
    {
        //根据指定路径返回文件类型
        FileInfo fileInfo = new FileInfo(fileName);  
        return (FileType)Enum.Parse(typeof(FileType), fileName);
    }
}

实现简单的客户端,并根据所需进行文件的加载:

public static void Main()
{
    //启动文件加载器
    LoadManager loadManager = new LoadManager();
    loadManager.LoadFiles(new WORDFile());
    loadManager.LoadFiles(new BusinessLogicImage());
    //...
}

随需而变的业务

新的视频格式出现:MPEG

 /// <summary>
/// 视频格式继承Files公用基类
/// </summary>
abstract class MediaFile : Files
{
}

首先是增加处理 MPEG 文件的类型
MPEGFile,并让它继承自 MediaFile,实现具体的 Open 方法即可。

 class MPEG : MediaFile
 {
     public override void Open()
     {
         Console.WriteLine("Open the MPEG file");
     }
 }

接着就是添加处理新文件的加载操作,如下:

 // 在没有对原系统进行修改的继承上,只需加入简单的类型和操作即可完成原来看似复杂的操作
 loadManager.LoadFiles(new MPEG());

事实证明,只要有更合理的设计与架构,在基于面向对象和.NET 框架的基础上,完全可以实现类
似于插件的可扩展系统,并且无需编译即可更新扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值