我的通用解耦非常丑陋
本文关键字:非常 解耦 我的 | 更新日期: 2023-09-27 17:51:11
我正在创建一个可以处理设置和加载/保存设置的dll。
我有一个设置类的属性,如string Path
, DateTime LastOpened
等。设置可以是任何东西,唯一的要求是它有一种默认值的方式。
有一个不同的类负责加载/保存设置。该类可以接受任何设置类并(反)序列化为任何文件格式。例如,它可以从XML文件中加载某种类型的设置,或者从JSON文件中加载相同类型的设置。
我的设计最终有点奇怪。
我为所有的设置类定义了一个接口,这样我就知道DefaultSettings()
是可用的。
interface ISettings<T>
{
T DefaultSettings();
}
我的设置类看起来像:
public class MySettings : ISettings<MySettings>
{
public DateTime LastOpened;
public string Path;
public MySettings DefaultSettings()
{
LastOpened = DateTime.Now;
Path = @"c:'";
}
}
实现类告诉它自己的接口看起来已经很奇怪了。
加载/保存类实现了这个接口:
interface ISettingsFile<T>
{
T Load(string file);
void Save();
}
假设我想从XmlSettingsFile<MySettings>
加载MySettings
。我必须写一些难看的东西,比如
MySettings mySettings = new MySettings();
XmlSettingsFile<MySettings> file = new XmlSettingsFile<MySettings>();
try {
mySettings = file.Load();
} catch (FileNotFoundException)
{
mySettings = mySettings.DefaultSettings();
}
这简直太奇怪和丑陋了。一定有更好的办法。
你有什么好主意吗?我不认为你的方法丑陋。使用中间字符串表示或类似的东西当然更好。
所以我会说你的方法很好,保持原样
这样如何:
interface ISettings
{
public string GetSetting(string settingName, string defaultValue);
}
所以不要尝试将设置表示为属性,而是使用命名值。这样就更容易考虑加载/保存设置,也更容易通过方法重载将职责传递给不同的类。如果你喜欢的话,你可以用动态模式来完成这些,但我个人喜欢这种模式,它让事情变得简单。
您也可以添加泛型,但您通常会发现这样的几个方法就足够了:
public bool GetSettingBool(string settingName, bool defaultValue);
这将抽象出您的阅读器实现(xml, json,等等)…
public interface IConfigurationReader
{
T Read<T>(string configKey);
}
public class Configuration
{
private readonly IConfigurationReader _reader;
public Configuration(IConfigurationReader reader)
{
_reader = reader;
}
public string Path
{
get
{
var path = _reader.Read<string>("Path");
return path;
}
}
}
public class ApplicationConfigFileReader : IConfigurationReader
{
public T Read<T>(string configKey)
{
var settingValue = System.Configuration.ConfigurationManager.AppSettings[configKey];
return (T)Convert.ChangeType(settingValue, typeof(T));
}
}
//sample usage
class Program
{
static void Main(string[] args)
{
IConfigurationReader reader = new ApplicationConfigFileReader();
var config = new Configuration(reader);
Console.WriteLine(config.Path);
Console.ReadKey();
}
}
My Reader实现只是作为框架类型的适配器,用于读取应用程序配置文件。
如果你有很多设置,按类别/区域将它们分组到单独的界面中是有益的。