班级的功能:
到目前为止,设计(非常愚蠢):
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的设计感到不安:
您能否就课程的界面设计提出一些建议,以便客户使用此课程更容易,更优雅?
答案 0 :(得分:3)
消费者类正在做MotionDetector应该做的工作。也许MotionDetector构造函数(或类中的某个方法)应该采用帧流,这项工作应该在内部完成。该算法运行后,该类应仅显示必需的图像数组。
答案 1 :(得分:1)
如果我理解你的问题,你不喜欢你班级的客户必须使用你提供的方法......左右 如何使框架处理类的属性而不是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);
}
编辑关于让消费者知道所捕获的群组,使用评论中建议的事件:
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*/));
}
}
}
答案 2 :(得分:1)
我可能会这样做:
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,然后FrameGroupListener执行它需要做的任何事情。
通过这种方式,类很好地与责任分开,而且很少以有状态的方式完成 - 所有状态都本地化到各个类。由于调用都是无效的,如果需要,可以将它们分派到任意线程。
FramePump可能会在某种定时器循环上被触发。
我可能会考虑将分组算法分解为一个单独的类 - 让运动检测器类向每个帧吐出一个bool,指示是否检测到运动,然后MotionGrouper类将单独采用这些类,根据所需的算法吐出帧列表。 “检测运动”和“确定如何对帧进行分组”显然是两个责任。但是,应该清楚如何在这种一般的管道设计中进行重构。