Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns C#如何拆分以下大型复杂类_Design Patterns_Oop_C# 3.0 - Fatal编程技术网

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

Design patterns C#如何拆分以下大型复杂类,design-patterns,oop,c#-3.0,Design Patterns,Oop,C# 3.0,我已经成功地将下面的THWorkingMemory类编程为一个反模式,即God对象。我计划它是一个相当小的类,大约有20个方法,但现在它包含了队列处理程序、计时器、线程、回调、powershell队列回调、事件处理程序、锁处理程序和大约50多个方法,即很多。这个类已经变得太大,无法维护,我需要将它分成更小的类。但是怎么做呢 THWorkingMemory类基本上定义了大约8个主代码块,这将建议8个独立的类,但是所有写入TreeDictionary的方法都使用ReaderWriterLockerR

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

THWorkingMemory类基本上定义了大约8个主代码块,这将建议8个独立的类,但是所有写入TreeDictionary的方法都使用ReaderWriterLockerRapper

这是代码

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() {}
}
接口i工作内存
{
受保护的CMemory数据库;
受保护的CMemory CCM{get{..}
公共广播活动。。
公共抽象void ExecuteAction(Guid ExecutionGuid,字符串jim……);
..
…20多种方法、事件
}
内部密封类CMemory
{
公共CMemory()
{
CBase=新的Treedical(新的比较器);
}   ..
}
公共密封类ExecutionState
{//20+个方法。它们作用于treedictionary节点}
内部密封类THWorkingMemory:IWorkingMemory
{   
lockStrategy=new ReaderWriterLockerRapper();
public void ExecuteAction(Guid ExecutionGuid,字符串jim…)
{
lockStrategy.AcquireWriteLock()
CCM[ExecutionGuid].CreateExecutionState(jim);
lockStrategy.ReleaseWriteLock()
}
2000多行方法、计时器、线程、事件、回调、,
队列处理。powershell脚本从ExecutionState回调,等等。
}
专用ReaderWriterLockerRapper
{
public void AcquireWriteLock(int超时){}\n
public void ReleaseWriteLock(){}
}
我看了一些关于部分类的问题,但它们写得不好。 这在这里是有意义的,因为THWorkingMemory类中的大多数方法都使用ReaderWriterLockerRapper

拆分THWorkingMemory的最佳方法是什么,这样可以保持lock类的准确性,也就是说,确保写入树字典不会发生冲突,即写入被锁定。我还研究了嵌套类,它可以作为一种解决方案,但不能像现在这样使用locker

有什么想法吗

我还研究了嵌套类,它可以作为一种解决方案,但不能像现在那样使用锁

如果嵌套类通过引用包含类进行实例化,那么它们可以使用locker,这样它们就可以使用实例成员数据和/或调用包含类的实例方法

例如,给定这样一个骨架

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


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

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接口,这样接口就可以传递给嵌套类了吗

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

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
}
注:

  • 您的主类现在变得简单/平凡:所有的复杂性都封装在嵌套类中
  • 每个嵌套类可能都有私有实现细节,它对其他类隐藏这些细节
  • 这些嵌套的类可能不需要嵌套:您可以将它们改为“
    内部
    ”类
  • 你的主课变成了一个学生
我会研究这些原则。尤其是单一责任原则。我发现它们在分析类以决定如何拆分时非常有用。我也使用Fowler的重构。有时,仅仅浏览一下,我就会发现一个我没有想到要使用的重构

我在检查函数时使用的一些一般准则:

  • 它是否依赖于任何私有类字段?如果不依赖,它将自动候选移动到单独的类
  • 该函数是否易于广义化?换句话说,它的逻辑是否与它所处理的类数据的结构相关联,或者经过一些小的修改,它是否可以用于其他地方。如果它可以广义化,则将其移动到一个单独的类中
当然,如果您有一组好的单元测试作为开始移动东西时的安全网,那么它将非常有帮助


你可能也对

感兴趣,嗨,克里斯,谢谢你这么快回来。我今晚和明天会看一看。鲍勃。嗨,克里斯,我看过了,但是解决方案能与来自iWorkingMemory的接口实现一起工作吗?我不明白你最近的评论/问题。嗯,THWorkingMemory类实现了IWorkingMemory接口,这样接口就可以传递给嵌套类了?Bobman真是太酷了。我甚至没有想过用这种方式来做。BAlfred,谢谢你修复我的编辑。Bob。