MVP와 특정 문제에 대한 저의 겸손한 견해입니다.
첫째 , 사용자가 상호 작용하거나 표시 할 수있는 모든 것이 뷰 입니다. 이러한 뷰의 법칙, 행동 및 특성은 인터페이스 로 설명됩니다 . 해당 인터페이스는 WinForms UI, 콘솔 UI, 웹 UI를 사용하여 구현할 수 있으며 UI를 전혀 사용하지 않을 수도 있습니다 (일반적으로 발표자를 테스트 할 때). 구체적인 구현은 뷰 인터페이스의 법칙을 준수하는 한 중요하지 않습니다. .
둘째 ,보기는 항상 발표자가 제어합니다 . 그러한 발표자의 법칙, 행동 및 특성도 인터페이스로 설명됩니다 . 해당 인터페이스는 뷰 인터페이스의 법칙을 준수하는 한 구체적인 뷰 구현에 관심이 없습니다.
셋째 , 발표자가보기를 제어하기 때문에 종속성을 최소화하기 위해보기가 발표자에 대해 아는 것이 전혀 없습니다. 발표자와보기간에 합의 된 계약이 있으며 이는보기 인터페이스에 의해 명시됩니다.
Third 의 의미 는 다음과 같습니다.
- 발표자는보기에서 호출 할 수있는 메서드가 없지만보기에는 발표자가 구독 할 수있는 이벤트가 있습니다.
- 발표자는 자신의 견해를 알고 있습니다. 구체적인 발표자에 생성자 주입을 사용하여이를 수행하는 것을 선호합니다.
- 보기는 어떤 발표자가 그것을 제어하고 있는지 전혀 모릅니다. 발표자에게 제공되지 않습니다.
귀하의 문제에 대해 위의 내용은 다소 단순화 된 코드로 표시 될 수 있습니다.
interface IConfigurationView
{
event EventHandler SelectConfigurationFile;
void SetConfigurationFile(string fullPath);
void Show();
}
class ConfigurationView : IConfigurationView
{
Form form;
Button selectConfigurationFileButton;
Label fullPathLabel;
public event EventHandler SelectConfigurationFile;
public ConfigurationView()
{
this.selectConfigurationFileButton.Click += delegate
{
var Handler = this.SelectConfigurationFile;
if (Handler != null)
{
Handler(this, EventArgs.Empty);
}
};
}
public void SetConfigurationFile(string fullPath)
{
this.fullPathLabel.Text = fullPath;
}
public void Show()
{
this.form.ShowDialog();
}
}
interface IConfigurationPresenter
{
void ShowView();
}
class ConfigurationPresenter : IConfigurationPresenter
{
Configuration configuration = new Configuration();
IConfigurationView view;
public ConfigurationPresenter(IConfigurationView view)
{
this.view = view;
this.view.SelectConfigurationFile += delegate
{
var selectFilePresenter = Gimme.The<ISelectFilePresenter>();
selectFilePresenter.ShowView();
this.configuration.FullPath = selectFilePresenter.FullPath;
this.view.SetConfigurationFile(this.configuration.FullPath);
};
}
public void ShowView()
{
this.view.SetConfigurationFile(this.configuration.FullPath);
this.view.Show();
}
}
위의 것 외에도 일반적으로 내 뷰가 일반적으로 혜택을받는 소유자 뷰 또는 뷰 제목을 IView
숨기는 기본 인터페이스가 Show()
있습니다.
귀하의 질문에 :
1. winform이로드되면 트 리뷰를 얻어야합니다. 따라서 뷰가 다음과 같은 메소드를 호출해야한다고 생각하는 것이 맞습니까? 발표자, 그러면 뷰로 전달되어 패널에 할당 될까요?
나는 부를 것이다 IConfigurationView.SetTreeData(...)
에서 IConfigurationPresenter.ShowView()
오른쪽으로 호출하기 전에,IConfigurationView.Show()
2. DataGridview도 있으므로 Winform의 모든 데이터 컨트롤에 대해 동일합니까?
네, 전화하겠습니다 IConfigurationView.SetTableData(...)
. 주어진 데이터의 형식을 지정하는 것은보기에 달려 있습니다. 발표자는 단순히 표 형식의 데이터를 원한다는보기의 계약을 따릅니다.
3. 내 앱에는 동일한 어셈블리를 가진 여러 모델 클래스가 있습니다. 또한 시작시로드해야하는 플러그인이있는 플러그인 아키텍처를 지원합니다. 뷰가 단순히 프레젠터 메서드를 호출하면 플러그인을로드하고 뷰에 정보를 표시하는 메서드가 호출됩니까? 그런 다음 어떤 계층이 플러그인 참조를 제어합니다. 보기가 그들 또는 발표자에 대한 참조를 보유합니까?
플러그인이보기와 관련된 경우보기는 해당 플러그인에 대해 알아야하지만 발표자는 알아야합니다. 모든 것이 데이터와 모델에 관한 것이라면 뷰는 그들과 관련이 없어야합니다.
4. 뷰가 트 리뷰 노드 색상에서 데이터 그리드 크기 등에 이르기까지 프레젠테이션에 대한 모든 것을 처리해야한다고 생각하는 것이 맞습니까?
예. 데이터를 설명하는 XML과 데이터를 가져와 CSS 스타일 시트를 적용하는 뷰를 제공하는 발표자로 생각하십시오. 구체적으로 말하면 발표자가 전화를 걸면 IRoadMapView.SetRoadCondition(RoadCondition.Slippery)
뷰가 도로를 빨간색으로 렌더링합니다.
클릭 한 노드의 데이터는 어떻습니까?
5. 트리 노드를 클릭 할 때 특정 노드를 통해 발표자에게 전달한 다음 발표자가 필요한 데이터를 파악한 다음보기에 다시 표시하기 전에 해당 데이터를 모델에 요청해야합니까?
가능하면 뷰에 트리를 한 번에 표시하는 데 필요한 모든 데이터를 전달합니다. 그러나 일부 데이터가 너무 커서 처음부터 전달할 수 없거나 그 특성이 동적이고 모델의 "최신 스냅 샷"이 필요한 경우 (프레젠터를 통해) event LoadNodeDetailsEventHandler LoadNodeDetails
보기 인터페이스에 다음과 같은 것을 추가 합니다. 발표자는 그것을 구독하고, LoadNodeDetailsEventArgs.Node
모델 에서 (아마도 어떤 종류의 ID를 통해) 노드의 세부 사항을 가져 와서 이벤트 핸들러 델리게이트가 반환 할 때 뷰가 표시된 노드 세부 사항을 업데이트 할 수 있습니다. 좋은 사용자 경험을 위해 데이터를 가져 오는 속도가 너무 느릴 수있는 경우 이러한 비동기 패턴이 필요할 수 있습니다.