2011-07-23 9 views
1

私はLinqToSQLと多層を持つASP.Net MVCプロジェクトに参加しています。ユーザーは基本的にExcelファイルとアクセスファイルをアップロードし、私のサービス層はすべての検証やその他の作業を行います。抽象クラスの子クラスのインスタンス化に関する疑問

私は、 "UploadManager"という名前の抽象クラスと "UploadExcel"と "UploadAccess"の2つの子クラスを実装することを考えていました。いくつかのメソッドは、 "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()」、アクセスファイルの場合は「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

あなたが次に抽象クラスと2人の子供

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 interface IUserDataManager 
{ 
    void SaveFile(); 
    void DeleteFile(); 
    void Validate(); 
} 

を定義することができますこれは、擬似コード:まず

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

    protected void DeleteFile(string fileName) 
    { 
     //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:コード内

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

どこかにあなたがコレクションを持っていますksはUploadManagerタイプのみであるため、必要なファイルタイプのアップローダの具体的な実装よりも明確な抽象レイヤを作成できます。

よろしくお願いいたします。

完了。

関連する問題