C#如何拆分以下大型复杂类

时间:2009-09-23 22:32:11

标签: design-patterns oop c#-3.0

我设法将以下THWorkingMemory类编程为反模式,上帝对象。我计划它是一个相当小的类,有大约20种方法,但现在它包含了队列处理程序,计时器,线程,回调,powershell队列回调,事件处理程序,锁处理程序和大约50多种方法,即批次。这个课程已经变得太大而无法维护,我需要分成更小的课程。但怎么办呢?

THWorkingMemory类从根本上定义了大约8个主要代码块,它们建议8个单独的类,但是写入TreeDictionary的所有方法都使用ReaderWriterLockerWrapper。

这是代码。

interface IWorkingMemory
{
protected CMemory CBase;
protected CMemory CCM { get { .. } 
public abtract event .. 
public abstract void ExecuteAction(Guid ExecutionGuid, string jim ... ...);
    ..
..20+ methods, events   
}

internal sealed class CMemory
{
    public CMemory()
    {
        CBase=new TreeDictionary<Guid, ExecutionState>(new comparer);
    }   ..
}


public sealed class ExecutionState 
{ // 20+ methods. that act against the treedictionary node  }

internal sealed class THWorkingMemory:IWorkingMemory
{   
    lockStrategy = new ReaderWriterLockerWrapper();

    public void ExecuteAction(Guid ExecutionGuid, string jim ... ...)
    {

        lockStrategy.AcquireWriteLock()
            CCM[ExecutionGuid].CreateExecutionState(jim);
        lockStrategy.ReleaseWriteLock()
    }

    2000 lines+ of methods, timers, threading, events, callbacks, 
        queues processing. powershell script callbacks from ExecutionState, etc.
}

private ReaderWriterLockerWrapper
{
    public void AcquireWriteLock(int timeout) {}\n
    public void ReleaseWriteLock() {}
}

我看过有关部分课程的问题,但是他们没有得到很好的写作。 这里有意义,因为THWingMemory类中的大多数方法都使用ReaderWriterLockerWrapper。

分割THWorkingMemory的最佳方法是什么,因此它保留了锁类的准确性,即确保写入树字典不会发生冲突,即写入被锁定。我还查看了嵌套类,它可以作为解决方案,但不能以与现在相同的方式使用锁定器。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

  

我还查看了嵌套类,它可以作为解决方案,但不能以与现在相同的方式使用锁定器。

嵌套类如果使用对包含类的引用进行实例化,则可以使用该锁,以便它们可以使用实例成员数据和/或调用包含类的实例方法。

例如,给出这样的骨架......

class THWorkingMemory
{
  class NestedClass
  {
    THWorkingMemory m_self;
    internal NestedClass(THWorkingMemory self)
    {
      m_self = self;
    }

    ... methods of NestedClass can invoke m_self.ExecuteAction
        and/or can access m_self.lockStrategy ...
  }

  NestedClass m_nestedClass;

  internal THWorkingMemory()
  {
    m_nestedClass = new NestedClass(this);
  }
}

...您可以将方法/功能移出THWorkingMemory类并移入NestedClass。


或者,您可以只将要共享的数据和方法包装到类中,并将对该类的引用(而不是对整个容器的引用)传递到嵌套类[es]。

class THWorkingMemory
{
  class SharedData
  {
    lockStrategy = new ReaderWriterLockerWrapper();

    public void ExecuteAction(Guid ExecutionGuid, string jim ... ...)
    {
      lockStrategy.AcquireWriteLock()
      CCM[ExecutionGuid].CreateExecutionState(jim);
      lockStrategy.ReleaseWriteLock()
    }
  }

  class NestedClass
  {
    SharedData m_sharedData;
    internal NestedClass(SharedData sharedData)
    {
      m_sharedData = sharedData;
    }

    ... methods of NestedClass can invoke m_sharedData.ExecuteAction
        and/or can access m_sharedData.lockStrategy ...
  }

  SharedData m_sharedData;
  NestedClass m_nestedClass;

  internal THWorkingMemory()
  {
    m_sharedData = new SharedData();
    m_nestedClass = new NestedClass(m_sharedData);
  }
}

修改

  

那么,THWorkingMemory内存类实现了IWorkingMemory接口,以便接口能够传递给嵌套类?

我认为你通过在主类中定义方法来实现主类中的接口,但是通过委托嵌套类中的相应方法来实现这些方法,例如:

interface IWorkingMemory
{
  void SomeMethod();
  void AnotherMethod();
  ... + 20 other methods ...
}

class THWorkingMemory : IWorkingMemory
{
  class NestedClass
  {
    public void SomeMethod()
    {
      ... some complicated implementation here ...
    }

    ... + plus private methods which help to implement the public method ...
  }

  class AnotherNestedClass
  {
    public void AnotherMethod()
    {
      ... some complicated implementation here ...
    }

    ... + plus private methods which help to implement the public method ...
  }

  SharedData m_sharedData;
  NestedClass m_nestedClass;
  AnotherNestedClass m_anotherNestedClass;

  internal THWorkingMemory()
  {
    m_sharedData = new SharedData();
    m_nestedClass = new NestedClass(m_sharedData);
    m_anotherNestedClass = new AnotherNestedClass(m_sharedData);
  }

  #region implement IWorkingMemory methods

  public void SomeMethod()
  {
    //implement by delegating to the implementation in the nested class
    m_nestedClass.SomeMethod();
  }

  public void AnotherMethod()
  {
    //implement by delegating to the implementation in the nested class
    m_anotherNestedClass.AnotherMethod();
  }

  ... + 20 other methods ...

  #endregion
}

注意:

  • 您的主类现在简单/平凡:所有复杂性都嵌套在嵌套类
  • 每个嵌套类都可能具有隐藏在其他类中的私有实现细节
  • 这些嵌套类可能不需要嵌套:您可以将它们设为“internal”类
  • 您的主要课程已成为Facade

答案 1 :(得分:1)

我会研究SOLID原则。特别是单一责任原则。我发现它们在分析类时决定如何拆分它们非常有用。我也使用福勒的重构catalog。有时只是通过浏览它,我会遇到一个我没想过要使用的重构。

我在检查函数时使用的一些通用指南:

  • 它依赖于任何私有类字段吗?如果它不是自动候选人转移到单独的班级。
  • 这个功能可以轻松推广吗?换句话说,它的逻辑是否与它操纵的类数据的结构相关联,或者可以在其他地方使用小的修改。如果它可以被推广,则将其移至单独的类中。

当然,如果你有一套好的单元测试作为安全网,当你开始移动时,它会有很大的帮助。

您可能也对http://refactormycode.com/

感兴趣