2016-11-07 61 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