C# 在这种情况下使用什么设计模式?
我有40家供应商需要建立ftp连接,在那里做些事情并关闭连接。因此,这40家供应商都有自己的类别,他们都有ftp服务器的连接和断开,但他们都有不同的处理方法 所以基本上我有40个使用这种方法的类:C# 在这种情况下使用什么设计模式?,c#,design-patterns,C#,Design Patterns,我有40家供应商需要建立ftp连接,在那里做些事情并关闭连接。因此,这40家供应商都有自己的类别,他们都有ftp服务器的连接和断开,但他们都有不同的处理方法 所以基本上我有40个使用这种方法的类: ftp.Connect(); //do something - this is different for all the classes ftp.Close(); 所以“做某事”部分对所有人来说都是不同的,它做不同的事情,使用不同的变量,等等 我想我要做的是:创建一个新类,它将在所有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*/);
process(string fileName) //and it would download fileName
process(string folderName) //create folder if it doesnt exist
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);
}
}
我这里的问题是,所有40家供应商的所有方法都有不同的输入参数,那么流程的输入参数是什么?另外,我认为我没有获得太多,因为我这里仍然有FtpConnection ftp参数,这意味着我必须在每个使用Connect方法的项目中添加具有FtpConnection类的dll
例如,供应商的流程方法如下所示:
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*/);
process(string fileName) //and it would download fileName
process(string folderName) //create folder if it doesnt exist
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);
}
}
这里有没有一种设计模式可以更简洁、更简单?创建抽象类
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,在该类中,您将作为属性(folderName、fieldName等)实现DoSomething方法的每个输入参数
最后在供应商A
public class SupplierA:BaseSupplier
{
public override void DoSomething(SupplierSettingClass settings)
{
//Do specific stuff for your class.
}
}
您可以使用一些巧妙的继承在一个基本
抽象类中包含几乎所有必需的行为,如下所示:
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*/);
process(string fileName) //and it would download fileName
process(string folderName) //create folder if it doesnt exist
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);
或
我的印象是,这样一个物体只用于短期和单一的特定目的。因此,我将接受存储在特定派生类中的特定参数。与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等人中,模板方法直接在行为模式一章中的策略之后描述。您可以简单地覆盖过程
方法(参数为列表
),或者我可能遗漏了什么?连接/关闭实际上可以是构造函数/处置(一种用语句替换的能力),请参见IDisposable
。对于不同的方法,您可以使用泛型作为设置类提供参数,例如,使用(var connection=new FTPConnection(…){…}
,甚至可以将设置实例设置为构造函数参数,然后访问,而无需为每个进程()
调用提供它