多类共用设置的最佳存储模式

4
我正在创建两个不同的类来访问自定义文件。我们称这些类为MyReaderMyWriter
我正在遵循与.NET类(如StreamReaderStreamWriter)相同的模式,其中有一个专门用于读取和写入的类。除了遵循已建立的模式外,这也解决了一些其他问题。
然而,我确实需要一些通用设置适用于读取器和编写器类。例如,我有一个分隔符字符,用户应该能够更改。我还有一些包含用于解析的常见信息的固定数据。
有人能建议一个好的模式,特别是遵循常见的.NET框架实践,用于创建多个类的通用设置吗?我的类已经继承了.NET类。似乎多重继承可能是一种方法,但在C#中似乎不被支持。
(我正在使用Visual Studio 2012。)
4个回答

3
public interface IStreamFilter
{
   string Delimiter {get; private set;}
   List<string> FilterCriteria {get; private set;}
}

public class StreamFilter : IStreamFilter
{
   public string Delimiter {get;}
   public List<string> FilterCriteria {get;}

   public void StreamFilter (string delimiter, List<string> filterCriteria)
   {
       this.Delimiter = delimiter;
       this.FilterCriteria = filterCriteria;
   }
}

您可以在Reader和Writer类的构造函数中传递IStreamFilter实例。

 public class MyReader
 {
      private IStreamFilter _streamFilter;

      public MyReader(IStreamFilter streamFilter)
      {
           this._streamFilter = streamFilter;
      }

      public string ReadString()
      { 
          var readString = reader.GetString(x => x.Contains(this._streamFilter.Delimiter);
           // apply the filter for reading string
      }
 }   

在您想实例化MyReader类的代码中的任何位置,您可以创建一个新的IStreamFilter实例,并根据用户喜好(例如从用户配置文件中获取)在构造函数中设置分隔符和其他过滤器条件。然后将该StreamFilter实例传递给您的MyReader实例。这样,您就可以根据需要自定义过滤器设置,而不必依赖单例模式。


1

尝试使用接口。 interface 类似于 abstract class,但只能包含方法或属性定义,由实现它们的类来“充实”它们。然后,类可以实现您需要的任意数量的接口。看一下 IEnumerable 如何允许列表、字典和数组共享一组公共方法,从而使它们可以在 foreach 中使用,或者如何 IDisposable 允许在 using 中声明类。

我制作了一组墨水文本框控件,它们都应该从多个应用程序的用户配置中获取其显示样式设置,因此我让它们从 IInkInputSettings 接口中获取这些设置,并在所有应用程序的 UserConfig 类中实现了该接口。

或者,您可以通过 Singleton 实现全局配置:

public class GlobalConfig{
    /* your configuration properties here */
    private static GlobalConfig instance = null;
    public static GlobalConfig Instance{
        get{
            if(instance == null) instance=new GlobalConfig();
            return instance;
        }
    }
    private GlobalConfig(){ /* set default property values */ }
}

这比具有静态成员的静态类更好,因为它只在第一次使用时实例化。


谢谢,但我不太确定这会如何帮助。它将定义接口,但我仍然需要在两个不同的地方实现该接口。我的理想情况是用户可以在一个地方设置例如分隔符字符,并且它会影响阅读器类和编写器类。 - Jonathan Wood
你想让它影响两个类的每个实例吗?你可以使用单例来实现。 - Patrick
我不确定。你能详细说明一下如何使用我所描述的这两个类来实现吗? - Jonathan Wood

1

这似乎是那些罕见的情况之一,单例模式可能是有意义的:

public abstract class MyBase
{
    // This is the .NET class you're inheriting from, just putting it as a placeholder.
}

public class MyReader : MyBase
{
    private static readonly IMySettings settings = MySettings.Instance;
}

public class MyWriter : MyBase
{
    private static readonly IMySettings settings = MySettings.Instance;
}

internal interface IMySettings
{
    // Define your setting's properties, such as delimiter character.
}

internal sealed class MySettings : IMySettings
{
    private MySettings()
    {
    }

    public static IMySettings Instance
    {
        get
        {
            return Nested.Instance;
        }
    }

    // Implement your setting's properties, such as delimiter character.

    private static class Nested
    {
        private static readonly IMySettings instance = new MySettings();

        // Explicit static constructor to tell C# compiler not to mark type as beforefieldinit
        static Nested()
        {
        }

        public static IMySettings Instance
        {
            get
            {
                return instance;
            }
        }
    }
}

希望这能有所帮助。

谢谢。我现在才有时间仔细研究这个问题。但说实话,我不明白为什么需要大部分的代码。由于所有MyReaderMyWriter实例都引用相同的MySettings实例,为什么不直接将MySettings设置为静态并直接引用它呢?为什么需要所有这些接口、继承和私有类呢? - Jonathan Wood
单元测试性,松散耦合,仍然可以使用对象继承(如果需要)。这些只是一些。我更倾向于使用 tranceporter 并通过构造函数注入它们,但 .NET FCL 并不是这样做的,我试图用一些额外的最佳实践来模拟它。 - Jesse C. Slicer

1

您可以使用基于构造函数的依赖注入将设置类插入到其他类中。很容易让IoC容器启动一个设置类(无论是单例还是非单例),并根据基类或接口进行注入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接