该类的功能:


接收图像帧序列,该序列是无限的。
检测框架中是否有运动。
根据特定算法对运动帧进行分组。


到目前为止,设计是(非常愚蠢的):

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的以下设计感到不舒服:


获取图像组的方式。
放置静止框架的方式。
通知客户端该组已捕获的方式。


您可以针对类的界面设计提供一些建议,以使客户端使用此类更容易,更优雅吗?

最佳答案

我可能会做这样的事情:

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()存储了帧,否则您必须将其保存在待处理列表中,直到需要删除它为止。无论如何,FramePump从实际的设备/文件中获取单个帧。这就是工作。 MotionDetector负责检测运动,并将其中包含运动的帧组传递给FrameGroupListener,然后由它执行所需的操作。

这样,可以很好地将各个类与职责分开,并且很少以有状态的方式完成-所有状态都局限于单个类。由于调用都是无效的,因此可以根据需要将它们分派到任意线程。

FramePump可能在某种计时器循环上触发。

我可能会考虑将分组算法分为一个单独的类-使motiondetector类将每个帧吐出一帧,并指示是否检测到运动的布尔值,然后MotionGrouper类将它们单独放入并吐出列表根据所需的算法选择帧数。很明显,“检测运动”和“确定如何对框架进行分组”是两个职责。但是,应该很清楚在这种一般的管道设计中如何进行重构。

关于c# - 丑陋的类接口(interface)定义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2377798/

10-13 08:28