我的通用解耦非常难看

时间:2014-03-21 12:29:13

标签: c# oop

我正在创建一个可以处理设置和加载/保存设置的dll。

我的设置类包含string PathDateTime 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();
}

假设我想从MySettings加载XmlSettingsFile<MySettings>。 我必须写一些丑陋的东西,如

MySettings mySettings = new MySettings();
XmlSettingsFile<MySettings> file = new XmlSettingsFile<MySettings>();
try {
    mySettings = file.Load();
} catch (FileNotFoundException)
{
    mySettings = mySettings.DefaultSettings();
}

这太奇怪和丑陋了。必须有更好的方法来做到这一点。

你有什么好主意吗?

3 个答案:

答案 0 :(得分:2)

我认为你的做法并不丑陋。使用中间字符串表示或类似的东西当然更好。

因此我会说你的方法很好,保持原样。

答案 1 :(得分:0)

这样的事情怎么样:

interface ISettings 
{ 

    public string GetSetting(string settingName, string defaultValue);

} 

所以不要试图将设置表示为属性,而是使用命名值。这使得更容易考虑加载/保存设置,并且更容易使方法重载以将责任传递给不同的类。如果你愿意的话,你可以用动态完成这一切,但我个人喜欢这种模式,它让事情变得简单。

您也可以添加泛型,但通常我会发现这样的一些方法就足够了:

    public bool GetSettingBool(string settingName, bool defaultValue);

答案 2 :(得分:0)

这会抽象出你的读者实现(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();
    }
}

我的Reader实现只是作为读取应用程序配置文件的框架类型的适配器。

如果您有很多设置,按类别/区域将它们分组到不同的界面中会很有用。