该类的功能:
接收图像帧序列,该序列是无限的。
检测框架中是否有运动。
根据特定算法对运动帧进行分组。
到目前为止,设计是(非常愚蠢的):
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/