Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.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
C# 丑陋的类接口定义_C#_Class Design - Fatal编程技术网

C# 丑陋的类接口定义

C# 丑陋的类接口定义,c#,class-design,C#,Class Design,该类的功能: 接收一系列图像帧,序列是无限的。 检测帧中是否有运动。 根据特定算法对运动帧进行分组。 到目前为止,设计都很愚蠢: class MotionDetector { //detect motion in the frame, return true if the group is captured. //frameToDispose is the frame that need be dispose, or for further process.

该类的功能:

接收一系列图像帧,序列是无限的。 检测帧中是否有运动。 根据特定算法对运动帧进行分组。 到目前为止,设计都很愚蠢:

class MotionDetector
{ 
      //detect motion in the frame, return true if the group is captured. 
      //frameToDispose is the frame that need be dispose, or for further process.
      public bool ProcessFrame(Frame in, out frameToDispose); 
    }
消费者协会:

public void Foo()
{
     bool groupCaptured = motionDetector.ProcessFrame(nextFrame, out lastFrame);

    if (IsStaticFrame(lastFrame)) { lastFrame.Dispose(); }
    else { imagesArray.Add(lastFrame); }

    if(groupCaptured) { processImageGroup(imagesArray);  }
}
我对MotionDetector的以下设计感到不舒服:

获取图像组的方法。 处理静止帧的方法。 通知客户端已捕获组的方法。
您能否就类的接口设计提供一些建议,以便客户端更容易、更优雅地使用该类?

如果我正确理解了您的问题,您会不喜欢类的客户端必须使用您提供的方法的方式。。。 让框架处理类的属性而不是out参数怎么样

class MotionDetector{ 

  public bool PreProcessFrame(Frame in); 

  public Frame frameToDispose{
    get;        
  }      
}
然后你可以像这样使用它:

bool groupCaptured = motionDetector.ProcessFrame(nextFrame);
if (IsStaticFrame(motionDetector.frameToDispose)){
  // ...
}
否则,如果对您的应用程序有意义,您可以这样做:

class MotionDetector{       
  // returns frame to dispose if sucessful, null otherwise
  public Frame PreProcessFrame(Frame in); 
}
public class MotionDetector
{
    private IFrameGroupListener m_listener;

    public MotionDetector(IFrameGroupListener listener)
    {
        m_listener = listener;
    }

    public void NewFrame(Frame f)
    {
        if(DetectMotion(f))
        {
            var group = GetCaptureGroup();
            m_listener.ReceiveFrameList(group);
        }
    }
}

public interface IFrameGroupListener
{
    void ReceiveFrameList(IList<Frame> captureGroup);
}

public class FramePump
{
    private MotionDetector m_detector;

    public FramePump(MotionDetector detector)
    {
        m_detector = detector;
    }

    public void DoFrame()
    {
        Frame f = GetFrameSomehow();
        m_detector.NewFrame(f);
    }

}
编辑关于使用评论中建议的事件让消费者知道捕获的组:

class GroupCapturedEventArgs : EventArgs{
  // put relevant information here...
}
class MotionDetector{
  public event EventHandler<GroupCapturedEventArgs> GroupCaptured;
  // then somewhere in your code:
  private vois SomeMethod() {
    // a group captured
    if (GroupCaptured != null) {
      GroupCaptured (this,new GroupCapturedEventArgs(/*whatever*/));
    }
  }      
}

如果我正确理解了您的问题,那么您不喜欢您的类的客户机必须使用您提供的方法的方式。。。 让框架处理类的属性而不是out参数怎么样

class MotionDetector{ 

  public bool PreProcessFrame(Frame in); 

  public Frame frameToDispose{
    get;        
  }      
}
然后你可以像这样使用它:

bool groupCaptured = motionDetector.ProcessFrame(nextFrame);
if (IsStaticFrame(motionDetector.frameToDispose)){
  // ...
}
否则,如果对您的应用程序有意义,您可以这样做:

class MotionDetector{       
  // returns frame to dispose if sucessful, null otherwise
  public Frame PreProcessFrame(Frame in); 
}
public class MotionDetector
{
    private IFrameGroupListener m_listener;

    public MotionDetector(IFrameGroupListener listener)
    {
        m_listener = listener;
    }

    public void NewFrame(Frame f)
    {
        if(DetectMotion(f))
        {
            var group = GetCaptureGroup();
            m_listener.ReceiveFrameList(group);
        }
    }
}

public interface IFrameGroupListener
{
    void ReceiveFrameList(IList<Frame> captureGroup);
}

public class FramePump
{
    private MotionDetector m_detector;

    public FramePump(MotionDetector detector)
    {
        m_detector = detector;
    }

    public void DoFrame()
    {
        Frame f = GetFrameSomehow();
        m_detector.NewFrame(f);
    }

}
编辑关于使用评论中建议的事件让消费者知道捕获的组:

class GroupCapturedEventArgs : EventArgs{
  // put relevant information here...
}
class MotionDetector{
  public event EventHandler<GroupCapturedEventArgs> GroupCaptured;
  // then somewhere in your code:
  private vois SomeMethod() {
    // a group captured
    if (GroupCaptured != null) {
      GroupCaptured (this,new GroupCapturedEventArgs(/*whatever*/));
    }
  }      
}

消费者类正在做MotionDetector应该做的工作。也许MotionDetector构造函数或类中的某个方法应该获取帧流,并且这项工作应该在内部完成。运行算法后,该类应仅公开必需的图像数组。

消费者类正在做MotionDetector应该做的工作。也许MotionDetector构造函数或类中的某个方法应该获取帧流,并且这项工作应该在内部完成。在算法运行后,类应该只公开必需的图像数组。

我可能会这样做:

class MotionDetector{       
  // returns frame to dispose if sucessful, null otherwise
  public Frame PreProcessFrame(Frame in); 
}
public class MotionDetector
{
    private IFrameGroupListener m_listener;

    public MotionDetector(IFrameGroupListener listener)
    {
        m_listener = listener;
    }

    public void NewFrame(Frame f)
    {
        if(DetectMotion(f))
        {
            var group = GetCaptureGroup();
            m_listener.ReceiveFrameList(group);
        }
    }
}

public interface IFrameGroupListener
{
    void ReceiveFrameList(IList<Frame> captureGroup);
}

public class FramePump
{
    private MotionDetector m_detector;

    public FramePump(MotionDetector detector)
    {
        m_detector = detector;
    }

    public void DoFrame()
    {
        Frame f = GetFrameSomehow();
        m_detector.NewFrame(f);
    }

}
我假设DetectMotion存储帧,否则您必须将其保留在挂起列表中,直到将其清除为止。无论如何,帧泵从实际设备/文件中获取单个帧。这就是我的工作。MotionDetector负责检测运动,并将包含运动的帧组传递给FrameGroupListener,然后后者执行它需要执行的任何操作

通过这种方式,类与职责很好地分离,很少以有状态的方式完成—所有状态都本地化到单个类。由于这些调用都是无效的,如果需要,可以将它们分派到任意线程

帧泵可能会在某种计时器循环上触发


我可能会考虑将分组算法分解成一个单独的类——让MODECT检测器类将每一帧吐出一个表示是否检测到运动的布尔值,然后MOTIONGNOPER类将逐个地检测这些帧,并根据所需的任何算法吐出帧列表。“检测运动”和“确定如何对帧进行分组”显然是两项职责。但是,在这种一般的管道设计中,应该清楚地知道如何进行重构。

我可能会这样做:

class MotionDetector{       
  // returns frame to dispose if sucessful, null otherwise
  public Frame PreProcessFrame(Frame in); 
}
public class MotionDetector
{
    private IFrameGroupListener m_listener;

    public MotionDetector(IFrameGroupListener listener)
    {
        m_listener = listener;
    }

    public void NewFrame(Frame f)
    {
        if(DetectMotion(f))
        {
            var group = GetCaptureGroup();
            m_listener.ReceiveFrameList(group);
        }
    }
}

public interface IFrameGroupListener
{
    void ReceiveFrameList(IList<Frame> captureGroup);
}

public class FramePump
{
    private MotionDetector m_detector;

    public FramePump(MotionDetector detector)
    {
        m_detector = detector;
    }

    public void DoFrame()
    {
        Frame f = GetFrameSomehow();
        m_detector.NewFrame(f);
    }

}
我假设DetectMotion存储帧,否则您必须将其保留在挂起列表中,直到将其清除为止。无论如何,帧泵从实际设备/文件中获取单个帧。这就是我的工作。MotionDetector负责检测运动,并将包含运动的帧组传递给FrameGroupListener,然后后者执行它需要执行的任何操作

通过这种方式,类与职责很好地分离,很少以有状态的方式完成—所有状态都本地化到单个类。由于这些调用都是无效的,如果需要,可以将它们分派到任意线程

帧泵可能会在某种计时器循环上触发


我可能会考虑将分组算法分解成一个单独的类——让MODECT检测器类将每一帧吐出一个表示是否检测到运动的布尔值,然后MOTIONGNOPER类将逐个地检测这些帧,并根据所需的任何算法吐出帧列表。“检测运动”和“确定如何对帧进行分组”显然是两项职责。但是,在这种一般的管道设计中,您应该清楚地知道如何进行重构。

您觉得不舒服的是什么?@Obalix,编辑添加了我不舒服的内容。您觉得不舒服的是什么?@Obalix,编辑添加了我不舒服的内容
t、 好的一点,关于如何让消费者知道该组被捕获以及如何获取该组呢?第三个例子是最干净的,依我看。当一个简单的空测试工作原理相同且更易于维护时,人们有时会对返回布尔值感到不安。至于让消费者知道该组被捕获的问题,为什么不使用事件?@Chris,我将尝试该事件。好的一点,如何让消费者知道该组已被捕获,以及如何获取该组?第三个示例是最干净的,在我看来,当一个简单的空测试工作原理相同且更易于维护时,人们有时会对返回布尔值感到厌烦。至于让消费者知道该组已被捕获的问题,为什么不使用事件?@Chris,我将尝试该事件。对不起,帧的序列是无限的。在这种情况下,它仍然可以使用流,但暴露不可变的IList。抱歉,帧的序列是无限的。在这种情况下,它仍然可以使用流,但暴露不可变的IList。