2016-11-07 15 views
4

私はftp接続を作成し、そこに何かして接続を閉じる必要のある40のサプライヤを持っています。だから、40人のサプライヤはすべて自分たちのクラスを持っていて、彼らはすべてftpサーバの接続と切断を持っていますが、それらはすべて異なった処理方法を持っています。だから、このような状況で使用するデザインパターンは何ですか?

ftp.Connect(); 
//do something - this is different for all the classes 
ftp.Close(); 

部分はすべてのために異なる何かをする、それは、それは異なるものを使用しない別の変数など

私が考えたもの:

だから基本的に私はこの方法で40回のクラスを持っています私は、すべての40のサプライヤでインスタンス化される新しいクラスを作成します。私がここに持っている問題は、すべての40社のサプライヤーのすべてのメソッドは、そのプロセスの入力パラメータは何でしょう異なる入力パラメータを持っているということです

public void Connect(FTPCredentials credentials, Process process) 
{ 
    var ftp = new FtpConnection(credentials.Host, credentials.Username, credentials.Password); 
    ftp.Open(); 
    ftp.Login(); 

    process(ftp); 

    ftp.Close(); 
} 

public delegate void Process(FtpConnection ftp/*, string name*/); 

:このクラスは、次のようになり一つの方法を持っているのだろうか?また、私はまだFtpConnection ftpパラメータを持っているので、私はあまり得られないと思います。つまり、Connectメソッドを使用するすべてのプロジェクトにFtpConnectionクラスを持つdllを追加する必要があります。

たとえば、仕入先での処理方法は、次のようになります。

process(string fileName) //and it would download fileName 
process(string folderName) //create folder if it doesnt exist 

私はそれがきれいになり、ここで使用することができますし、物事を簡単になるだろうデザインパターンがありますか?

+0

単に 'Process'メソッド(' List'のパラメータ)をオーバーライドするか、何か不足する可能性がありますか? – hofmeister

+1

接続/クローズは実際にコンストラクタ/ dispose(['using'](https://msdn.microsoft.com/en-us/library/yh598w02.aspx)ステートメントで置き換えることができます)、「IDisposable '。異なるメソッドについては、ジェネリックを使用してパラメータを設定クラスとして提供することができます。 '(var connection = new FTPConnection (...){...}'を使うと、設定のインスタンスはコンストラクタパラメータとして設定されても、 'Process()'の呼び出しごとに設定する必要はなく。 – Sinatr

答えて

0

最後に

public class SupplierSettingClass 
    { 
     public string FolderName {get; set;} 

     //and so on; 
    } 

を(フォルダ名、フィールド名など)を使用すると、プロパティとしてのdoSomethingメソッドのすべての入力パラメータを実装しますここであなたがSupplierSettingClassを作成する必要が

public abstract class BaseSupplier 
    { 

     public void Connect(FTPCredentials credentials, Process process, SupplierSettingClass settings) 
     { 
      var ftp = new FtpConnection(credentials.Host, credentials.Username, credentials.Password); 
      ftp.Open(); 
      ftp.Login(); 

      DoSomething(settings); 

      ftp.Close(); 
     } 

     public virtual void DoSomething(SupplierSettingClass settings) 
     { 
      //define base case; 
     } 
    } 

抽象クラスを作成します。サプライヤーA

public class SupplierA:BaseSupplier 
    { 
     public override void DoSomething(SupplierSettingClass settings) 
     { 
       //Do specific stuff for your class. 
     } 
    } 
0

Rの継承は、このように、一つの基地abstractクラスではかなり必要な行動のすべてを含むように:

Credentials creds = new Credentials() 
{ 
    Host = "127.0.0.1", 
    Username = "test", 
    Password = "test" 
}; 

MySupplier sup1 = new MySupplier(); 
sup1.SomeProperty = "Hello"; 
sup1.Process(creds); 

OR

using (MySupplier sup1 = new MySupplier()) 
{ 
    sup1.SomeProperty = "Hello"; 
    sup1.Process(creds); 
} 
:ここ
public interface IProcessor 
{ 
    void Process(Credentials credentials); 
} 

public class Credentials 
{ 
    public string Host { get; set; } 
    public string Username { get; set; } 
    public string Password { get; set; } 
} 

public abstract class SupplierBase : IProcessor, IDisposable 
{ 
    protected FtpConnection _Connection; 

    private void Connect(Credentials credentials) 
    { 
     //Create the ftp connection 
     _Connection = new FtpConnection(credentials.Host, credentials.Username, credentials.Password); 
     _Connection.Open(); 
     _Connection.Login(); 
    } 

    private void Disconnect() 
    { 
     //Close and dispose the ftp connection 
     _Connection.Close(); 
     _Connection.Dispose(); 
     _Connection = null; 
    } 

    public void Process(Credentials credentials) 
    { 
     Connect(credentials); 
     Execute(); 
     Disconnect(); 
    } 

    protected abstract void Execute(); 

    #region IDisposable 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_Connection != null) 
      { 
       _Connection.Dispose(); 
       _Connection = null; 
      } 
     } 
    } 

    #endregion 
} 

public void MySupplier : SupplierBase 
{ 
    //You can add unique supplier properties here. 
    public string SomeProperty { get; set; } 

    protected override void Execute() 
    { 
     //Implementation here 
     Console.WriteLine(SomeProperty); 
    } 
} 

は、あなたがそれを呼び出す方法の例です
1

私の印象は、このようなオブジェクトは短期間でのみ使用され、単一の特定の目的で使用されるということです。だから私は特定の派生クラスに格納される特定のパラメータを受け入れるだろう。 mybirthnameのソリューションと同様に、私は抽象クラスで始まりますが、違っそれを定義したい:

public abstract class BaseSupplier 
{ 
    protected BaseSupplier(FtpCredentials credentials) 
    { 
     _Credentials = credentials; 
    } 
    private FtpCredentials _Credentials; 

    public void Run() 
    { 
     Connect(); 
     Process(); 
     Disconnect(); 
    } 

    private void Connect() {/* your connection and login code */} 
    private void Disconnect() {/* your disconnect code */} 
    protected abstract void Process(); // to be filled in the derived class 
} 

public class ConcreteSupplier 
{ 
    public ConcreteSupplier(FtpCredentials credentials, SomeType parameter) : base(credentials) 
    { /* store extra parameters */ } 

    override Process() {/*your concrete processing code */ } 
} 

私の記憶が正しければ、それは戦略パターンと呼ばれています。

編集: ジュウナは正しく、テンプレートメソッドパターンです。ガンマ(Gamma)らは、「行動パターン」の章のストラテジーの後にテンプレートメソッドを直接記述している。

+1

*テンプレートメソッド*パターン – juunas

関連する問題