像DRY原则一样在c#中删除代码副本



我有这样的代码:

public interface IManager<T> where T : ConnectionOptions
public class XManager : IManager<ConnectionOptions>
{
private ModuleConnectionOptions _moduleConnectionOptions;
private void SetConnection(ModuleConnectionOptions moduleConnectionOptions)
{
var currentDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (currentDirectory == null)
{
throw new ArgumentException("Current directory path is not valid.");
}
_moduleConnectionOptions.LocalFolder = Path.Combine(currentDirectory, moduleConnectionOptions.LocalFolder);
}
}
public class YManager : IManager<ConnectionOptions>
{
private TestConnectionOptions _testConnectionOptions;
private void SetConnection(TestConnectionOptions testConnectionOptions)
{
var currentDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (currentDirectory == null)
{
throw new ArgumentException("Current directory path is not valid.");
}
_testConnectionOptions.LocalFolder = Path.Combine(currentDirectory, testConnectionOptions.LocalFolder);
}
}
public class ConnectionOptions
{
// empty constructor for serialization
public ConnectionOptions()
{
}
public ConnectionOptions(string localFolder)
{
LocalFolder = localFolder;
}
public string LocalFolder { get; set; }
}

TestConnectionOptions和ModuleConnectionOptions是ConnectionOptions的子类,并且有额外的属性。

这段代码很相似,而且相当重复。有更好的方法吗?谢谢你。

在进入解决方案之前:您是否真的需要Generic声明-始终牢记KISS原则,然后是DRY原则。我将在文章末尾将其从我的解决方案中完全删除:

我将看到如下内容:

创建如下接口:

public interface IConnectionOptions {
public string LocalFolder {get; set;}
}

并由TestConnectionOptionsModuleConnectionOptions实现。然后删除一个类,创建一个像这样的:

public class Manager : IManager<ConnectionOptions>
{
private IConnectionOptions connectionOptions;
private void SetConnection(IConnectionOptions connectionOptions)
{
var currentDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (currentDirectory == null)
{
throw new ArgumentException("Current directory path is not valid.");
}
this.connectionOptions.LocalFolder = Path.Combine(currentDirectory, connectionOptions.LocalFolder);
}
}

无泛型声明

/// Since there is only one instace, no need for generics
public class Manager: IManager
{
private IConnectionOptions connectionOptions;
private void SetConnection(IConnectionOptions connectionOptions)
{
var currentDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (currentDirectory == null)
{
throw new ArgumentException("Current directory path is not valid.");
}
this.connectionOptions.LocalFolder = Path.Combine(currentDirectory, connectionOptions.LocalFolder);
}
}

这个实现类似于@Athanasios Kataras的实现。唯一的区别是每个模块使用抽象泛型类和具体类。

public interface IManager<T> where T : IConnectionOptions
{
}
public abstract class AbcManager<T> : IManager<T> where T: IConnectionOptions
{
private IConnectionOptions _moduleConnectionOptions;
protected virtual void SetConnection(IConnectionOptions moduleConnectionOptions)
{
var currentDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (currentDirectory == null)
{
throw new ArgumentException("Current directory path is not valid.");
}
_moduleConnectionOptions.LocalFolder = Path.Combine(currentDirectory, moduleConnectionOptions.LocalFolder);
}
}
public class XManager : AbcManager<TestConnectionOptions>
{

}

public class YManager : AbcManager<ModuleConnectionOptions>
{

}
public class TestConnectionOptions : IConnectionOptions
{
public string LocalFolder { get; set; }
}
public class ModuleConnectionOptions : IConnectionOptions
{
public string LocalFolder { get; set; }
}
public interface IConnectionOptions
{
string LocalFolder { get; set; }
}

最新更新