重构单身过度使用

drh*_*ris 45 .net c# oop design-patterns

今天我顿悟了,而且我做错了.一些历史:我继承了一个C#应用程序,它实际上只是一个静态方法的集合,一个完全程序化的C#代码.我重构了这个当时最了解的,带来了大量的大学后OOP知识.长话短说,代码中的许多实体都变成了单身人士.

今天我意识到我需要3个新类,每个类都遵循相同的Singleton模式来匹配软件的其余部分.如果我一直在这个滑坡上翻滚,最终我的应用程序中的每个类都将是Singleton,这与原始静态方法组完全没有逻辑上的区别.

我需要帮助重新考虑这一点.我知道依赖注入,这通常是用来打破Singleton诅咒的策略.但是,我有一些与此重构相关的具体问题,以及所有关于这样做的最佳实践.

  1. 使用静态变量封装配置信息的可接受程度如何?我有一个使用静态的大脑块,我认为这是由于大学早期的OO课,教授说静态是坏的.但是,每次访问它时,我是否应该重新配置该类?访问硬件时,是否可以保留指向所需地址和变量的静态指针,还是应该继续执行Open()Close()操作?

  2. 现在我有一个方法充当控制器.具体来说,我不断轮询几个外部仪器(通过硬件驱动程序)获取数据.这种类型的控制器应该是可行的方法,还是应该在程序启动时为每个仪器生成单独的线程?如果是后者,我该如何使这个面向对象?我应该创建名为InstrumentAListener和的类InstrumentBListener吗?或者有一些标准的方法来解决这个问题吗?

  3. 有没有更好的方法来进行全局配置?现在我只是简单Configuration.Instance.Foo地在整个代码中洒满了.几乎每个班级都使用它,所以将它保持为Singleton是有道理的.有什么想法吗?

  4. 我的很多类的事情像SerialPortWriter或者DataFileWriter,必须坐下来等待这个数据流.因为他们是活跃的整段时间,我应该怎么才能监听,当数据进入生成的事件安排这些?

关于如何摆脱单身人士和其他模式过度使用的任何其他资源,书籍或评论将是有帮助的.

Are*_*ren 13

好吧,这是我攻击这个问题的最好机会:

(1)静力学

这个问题static是你可能有是,它意味着不同的东西在.NET和说,C++.静态基本上意味着它可以在类本身上访问.至于它的可接受性, id表示它更多的是你用来在类上进行非实例特定操作的东西.或者只是一般的事情Math.Abs(...).您应该用于全局配置的可能是用于保持当前/活动配置的静态访问属性.也许一些静态类用于加载/保存设置配置,但是配置应该是一个对象,因此它可以被传递操纵等公共类MyConfiguration {public const string DefaultConfigPath ="./ config.xml";

  protected static MyConfiguration _current;
  public static MyConfiguration Current
  {
    get
    {
      if (_current == null)
        Load(DefaultConfigPath);
      return _current;
    }
  }

  public static MyConfiguration Load(string path)
  {
    // Do your loading here
    _current = loadedConfig;
    return loadedConfig; 
  }

  // Static save function

  //*********** Non-Static Members *********//

  public string MyVariable { get; set; }
  // etc..
}
Run Code Online (Sandbox Code Playgroud)

(2)控制器/硬件

您应该研究一种被动方法,IObserver<>或者IObservable<>它是Reactive Framework(Rx)的一部分.

另一种方法是使用ThreadPool来安排轮询任务,因为如果你有很多硬件要汇集,你可能会得到大量的线程.在使用任何类型的线程之前请确保了解它.你甚至不会意识到犯错很容易.这本书是一个很好的来源,会教你很多.

无论哪种方式,您都应该构建用于管理硬件的服务(实际上只是一个名称),负责收集有关服务的信息(本质上是模型模式).从那里,您的中央控制器可以使用它们来访问数据,保持控制器中的程序逻辑和服务中的硬件逻辑.

(3)全局配置

我可能已经在第1点触及了这个主题,但通常我们去的地方,如果你发现自己打字过多,你总是可以把它拉出那里假设它.Instance是一个物体.

MyConfiguration cfg = MyConfiguration.Current
cfg.Foo // etc...
Run Code Online (Sandbox Code Playgroud)

(4)听取数据

反应框架可以再次帮助您,或者您可以构建一个事件驱动的模型,该模型使用触发器来传入数据.这样可以确保在数据进入之前不会阻塞线程.它可以大大降低应用程序的复杂性.