2016-11-07 89 views
4

我有40個供應商需要建立一個ftp連接,在那裏做一些事情並關閉連接。所以,這40家供應商都有自己的班級,他們都有連接和斷開的ftp服務器,但他們都有不同的處理方法。在這種情況下使用什麼設計模式?

所以基本上我有40個教學班,這個方法:

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

所以做一些部分是所有不同,它不同的東西,它使用不同的變量等

我想什麼我會做的是:創建一個新的類,將在所有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*/); 

我這裏的問題是,在所有的40個供應商的所有方法有不同的輸入參數,這樣你會過程的輸入參數是什麼?另外,我認爲我沒什麼好處,因爲我仍然有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

連接/關閉實際上可以是構造函數/處理(可以用['using'](https://msdn.microsoft.com/en-us/library/yh598w02.aspx)語句替換),請參閱'IDisposable '。至於不同的方法,您可以使用泛型來提供參數作爲設置類,例如使用(var connection = new FTPConnection (...){...}',設置的實例甚至可以設置爲構造函數參數,然後無需爲每個Process()調用提供它 – Sinatr

回答

0

創建抽象類

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

您需要創建SupplierSettingClass中,你將實現每個輸入參數DoSomething的方法,屬性(文件夾名,字段名等)

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

     //and so on; 
    } 

到底在供應商A

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

你可以使用一些cleve [R繼承包含幾乎所有所需的行爲的一個基本abstract類,像這樣:

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

這裏,你會怎麼稱呼它一個例子:

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

如果我沒有記錯,這就是所謂的策略模式。

編輯: juunas是正確的,它是模板方法模式。在Gamma等人的「行爲模式」一章中,模板方法直接在Strategy之後描述。

+1

*模板方法*模式 – juunas