2010-03-04 3 views
1

클래스의 기능 : 어글리 클래스 인터페이스 정의

  1. 이미지 프레임들의 시퀀스를 수신은 서열 무한이다.
  2. 프레임에 움직임이 있는지 감지합니다.
  3. 특정 알고리즘에 따라 모션 프레임을 그룹화합니다.

지금까지 디자인은 (꽤 바보)입니다 :

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의 디자인으로 불편

  1. 이미지 그룹을 얻는 방법.
  2. 움직이지 않는 프레임을 처리하는 방법.
  3. 캡처 된 그룹을 클라이언트에 알리는 방법.

클라이언트가이 클래스를 사용하는 것이 더 쉽고 쉽도록 클래스의 인터페이스 디자인에 대한 조언을 해줄 수 있습니까?

+0

당신이 불편 함을 느끼는 것은 정확히 무엇입니까? – AxelEckenberger

+0

@Obalix, 내가 편하지 않은 것을 추가하기 위해 편집 됨. – Benny

답변

1

은 아마 이런 식으로 뭔가를 할 거라고 그것을 없애라. 어쨌든 FramePump는 실제 장치/파일에서 개별 프레임을 가져옵니다. 그게 일이야. MotionDetector는 모션을 감지하고 모션이있는 프레임 그룹을 FrameGroupListener에 전달합니다. 그러면 프레임 그룹 리스너는 필요한 모든 작업을 수행합니다.

이렇게하면 클래스가 책임으로 잘 분리되고 상태 기반 방법으로는 거의 수행되지 않습니다. 모든 상태는 개별 클래스에 지역화됩니다. 호출은 모두 무효이므로 필요에 따라 임의의 스레드에 호출 할 수 있습니다.

아마도 FramePump는 일종의 타이머 루프에서 트리거됩니다.

그룹핑 알고리즘을 별도의 클래스로 나누는 것도 고려해 볼 수 있습니다. 모션 디텍터 클래스가 모션 감지 여부를 나타내는 bool과 함께 각 프레임을 뱉어 내고 MotionGrouper 클래스가 각 프레임을 개별적으로 가져 오도록하는 것이 좋습니다. 원하는 알고리즘에 따라 프레임 목록을 버리십시오. '움직임 감지'와 '프레임 그룹화 방법 결정'은 두 가지 책임 사항입니다. 그러나 이러한 일반적인 종류의 파이프 라인 디자인에서 리팩토링을 어떻게 수행해야하는지 분명해야합니다.

1

질문을 올바르게 이해했다면 클래스 클라이언트가 제공하는 메서드를 사용해야하는 방식이 마음에 들지 않습니다.
클래스 대신 클래스의 속성을 처리 할 프레임을 만드는 방법은 무엇입니까? 출력 매개 변수? 이 같이 할 수

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 MotionDetector{ 

    public bool PreProcessFrame(Frame in); 

    public Frame frameToDispose{ 
    get;   
    }  
} 

그럼 당신은 그것을 좋아 사용할 수 있습니다 코멘트에 제안 된대로 이벤트를 사용하여 캡처 된 그룹을 알 수 있습니다.

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*/)); 
    } 
    }  
} 
+0

좋은 점은 소비자가 그룹을 알게하고 그룹을 얻는 방법은 어떨까요? – Benny

+0

세 번째 예제는 가장 깨끗한 IMO입니다. 사람들은 간단한 null 테스트가 똑같이 작동하고 훨씬 더 유지 보수가 필요할 때 때때로 부울 값을 반환 할 때까지 기다리게됩니다. – Chris

+0

소비자가 그룹을 알게하는 것에 관한 질문은 왜 이벤트를 사용하지 않는 것이 좋습니까? – Chris

3

소비자 클래스는 MotionDetector가 수행해야하는 작업을 수행하고 있습니다. 아마도 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는() 프레임을 저장 있으리라 믿고있어 :

+0

죄송합니다. 프레임 시퀀스가 ​​무한합니다. – Benny

+0

이 경우에도 여전히 스트림을 사용할 수는 있지만 수정 불가능한 IList 이 노출 될 수 있습니다. –