我正在使用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()
”。
有没有办法实现这个目标?有没有更好的办法?我有点迷失......
提前致谢!!
答案 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();
}
}