怀疑实例化抽象类的子类

时间:2011-07-23 14:46:21

标签: c# asp.net-mvc-2 inheritance interface abstract-class

我正在使用LinqToSQL和多层的ASP.Net MVC项目。用户可以上传文件,基本上是Excel和Access文件,我的服务层将完成所有的验证和其他工作。

我正在考虑实现名为“UploadManager”的抽象类和2个子类:“UploadExcel”和“UploadAccess”。有些方法对两个类都是通用的,例如“SaveFile”和“DeleteFile”。但是,其他一些方法将仅限于特定的子类,例如“ValidateWorksheet”,它只属于“UploadExcel”类。

我正在设计这样的东西:

    public abstract class UploadManager
    {
        protected void SaveFile(string fileName)
        {
             //Implement
        }

        protected void DeleteFile(string fileName)
        {
             //Implement
        }
    }

   public class UploadExcel : UploadManager
   {
      private bool ValidateWorksheet()
      {
         //Implement
      }
   }

   public class UploadAccess : UploadManager
   {
      private bool ValidateSomethingAboutAccess()
      {
         //Implement
      }
   }

我也在考虑使用Interfaces。但是,我的主要疑问是我怎么知道我必须实例化哪个子类?如果上传的文件是Excel文件,则为“new UploadExcel()”,如果是Access文件,则为“new UploadAccess()”。

有没有办法实现这个目标?有没有更好的办法?我有点迷失......

提前致谢!!

5 个答案:

答案 0 :(得分:2)

可以做这样的事情, 伪代码

第一:

public abstract class UploadManager
{
   public void SaveFile(string fileName){ //uploading file }
   public abstract bool CanAccept(string sFileName); //abstract

    protected void DeleteFile(string fileName)
    {
       //Implement
    }
}

第二个具体实施:

 public class UploadExcel : UploadManager
   {
      public override bool CanAccept(string sFileName) {

           //if Excel file return true, else false
      }

      private bool ValidateWorksheet()
      {
         //Implement
      }
   }

   public class UploadAccess : UploadManager
   {
       public override bool CanAccept(string sFileName) {

           //if Access file return true, else false
      }
      private bool ValidateSomethingAboutAccess()
      {
         //Implement
      }
   }

代码中的某个地方有一个集合:

List<UploadManager> managers = new List<UploadManager>{ new UploadExcel(), new UploadAccess()};



//at the time decide to send a file (sFileName): 
UploadManager myUploadManager = managers.Find(manager=>{return manager.CanAccept(sFileName);});
myUploadManager.SaveFile(sFileName); //call concrete implementaiton for that specific file

该代码仅适用于UploadManager类型,因此您可以为任何所需的文件类型上传器创建任何具体实现的definit抽象层。

问候。

完成。

答案 1 :(得分:1)

基本思想是在基类中将validate方法作为abstract

然后在实例化时只需要担心子类,其余的只处理基类方法:

string fileName = ...;  // from your request somehow

UploadManager manager = null;  // note the type of manager, no var

if (System.IO.Path.GetExtension(filename).LowerCase().StartsWith("xls"))    
   manager = new UploadExcel ();  
else
   ...   

manager.Validate();  // calls the Excel or the Access override

你的课程看起来更像是

public abstract class UploadManager
{
    // SaveFile, DeleteFile

    public abstract bool Validate();
}


public class UploadExcel : UploadManager
{
      public override bool Validate()
      {
          // ...
          return ValidateWorksheet();
      }

      private bool ValidateWorksheet()
      {
         //Implement
      }
}

答案 2 :(得分:1)

我相信你要找的是Abstract factory design pattern

答案 3 :(得分:0)

根据我对您的问题的理解,您可以拥有上传管理器的缓存,以便在用户选择上传文件时,您可以获得与文件扩展名相关的管理器。即。

// Cache of upload managers keyed by their associated file extension
private Dictionary<string, UploadManager> mManagers;

    // ... Add managers to cache in constructor ...

public void Upload(string filename)
{
    string extension = System.IO.Path.GetExtension(filename);

    // See if we have a manager for this extension
    UploadManager manager;
    if(mManagers.TryGetValue(extension, out manager))
    {
        // Validate the file
        // Note: This will call an abstract method in the UploadManager base
        //   class that will be defined in the child classes.
        manager.Validate(filename);
    }
}

答案 4 :(得分:0)

您可以定义界面

public interface IUserDataManager
{
    void SaveFile();
    void DeleteFile();
    void Validate();
}

然后抽象类和两个孩子

public abstract class UserDataManager : IUserDataManager
{
    private readonly string filename;

    protected UserDataManager(string filename)
    {
        this.filename = filename;
    }

    public void SaveFile()
    {
        Console.WriteLine("File saved as: " + filename);
    }

    public void DeleteFile()
    {
        Console.WriteLine("File deleted: " + filename);
    }

    public abstract void Validate();
}

public class AccessUserDataManager : UserDataManager
{
    public AccessUserDataManager(string filename) : base(filename) { }

    public override void Validate()
    {
        Console.WriteLine("Access validated");
    }
}

public class ExcellUserDataManager : UserDataManager
{
    public ExcellUserDataManager(string filename) : base(filename) { }

    public override void Validate()
    {
        Console.WriteLine("Excel validated");
    }
}

这是如何使用它

class Program
{
    static void Main(string[] args)
    {
        IUserDataManager mgr = new AccessUserDataManager("access.db");
        mgr.Validate();
        mgr.SaveFile();
        mgr.DeleteFile();

        mgr = new ExcellUserDataManager("excel.xlsx");
        mgr.Validate();
        mgr.SaveFile();
        mgr.DeleteFile();

        Console.ReadLine();
    }
}