2011-07-23 25 views
1

我在使用LinqToSQL和多层的ASP.Net MVC项目。用户可以上传文件,基本上是Excel和Access文件,我的服务层将完成所有的验证和其他内容。关于实例化抽象类的子类的疑问

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

我设计是这样的:

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 
     } 
    } 

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

有没有办法做到这一点?有没有更好的办法?我有点不知所措...

在此先感谢!

回答

1

基本思想是在基类中实现验证方法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 
     } 
} 
+0

但是我怎么知道我是否必须做一个新的UploadExcel()或一个新的UploadAccess()? – AndreMiranda

+0

并假设我有一个关于Excel的具体方法?它将被限制在它的类别中... – AndreMiranda

+0

@Andre:会为你留下一些逻辑(if/else)。继承只能处理(可以做成)符合相同形状的事物。 –

0

基于我对你的问题的理解,你可以有一个上传管理器的缓存,使w如果用户选择上传文件,则可以使管理员与文件扩展名相关。即

// 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); 
    } 
} 
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(); 
    } 
} 
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 

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

问候。

完成。