我有一个MVP的实现,用于域模型中的项目列表。
我的问题一般是如何(或我可以)摆脱具体的View和Presenter中类型参数的重复?
我倾向于认为我遇到了限制,不得不忍受重复或重新设计课程。另一种选择是我错过了一些明显的东西。无论如何,这就是我在这里问的原因。
具体来说,如果你有:
interface IA<T2, T3> { }
class C<T1, T2, T3> where T1 : IA<T2, T3>
我可以让编译推断出类型参数T2和T3,结果如下:
interface IB : IA<int, string>
class D : C<IB> { } // can't do this
这个编译。重复参数为Note, string
和Attachment, string
。
// Abstract View
public interface IView<TItem, TKey>
{
void Fill(TItem[] items);
event SelectEvent<TKey> SelectionChanged;
event MessageEvent Add;
}
// Event Delegates
public delegate void SelectEvent<TKey>(TKey selectedValue);
public delegate bool MessageEvent();
// Model Entities
public class Note { }
public class Attachment { }
// Abstract Presenter
public abstract class Presenter<TView, TItem, TKey> where TView : IView<TItem, TKey>
{
protected TKey SelectedValue { get; private set; }
protected TView View { get; set; }
public Presenter(TView view)
{
View = (TView)view;
View.SelectionChanged += OnSelectionChangedInternal;
View.Add += OnAdd;
}
void OnSelectionChangedInternal(TKey selectedValue) {
this.SelectedValue = selectedValue;
OnSelectionChanged(selectedValue);
}
protected abstract void OnSelectionChanged(TKey selectedVaule);
protected abstract bool OnAdd();
}
// Concrete Views
public interface INotes : IView<Note, string> { }
public interface IAttachments : IView<Attachment, string> { }
// Concrete Presenters
public class NotesPresenter : Presenter<INotes, Note, string> {
public NotesPresenter(INotes view) : base(view) { }
protected override void OnSelectionChanged(string publisherName) { }
protected override bool OnAdd() { return false; }
}
public class AttachmentsPresenter : Presenter<IAttachments, Attachment, string> {
public AttachmentsPresenter(IAttachments view) : base(view) { }
protected override void OnSelectionChanged(string publisherName) { }
protected override bool OnAdd() { return false; }
}
答案 0 :(得分:0)
对演示者稍作修改。改为推断你的观点。由于您的具体视图实现了正确的界面,因此它可以工作见下面的代码。
// Abstract View
public interface IView<TItem, TKey>
{
void Fill(TItem[] items);
event SelectEvent<TKey> SelectionChanged;
event MessageEvent Add;
}
// Event Delegates
public delegate void SelectEvent<TKey>(TKey selectedValue);
public delegate bool MessageEvent();
// Model Entities
public class Note { }
public class Attachment { }
// Abstract Presenter
public abstract class Presenter<TItem, TKey>
{
protected TKey SelectedValue { get; private set; }
protected IView<TItem, TKey> View { get; set; }
public Presenter(IView<TItem, TKey> view)
{
View = view;
View.SelectionChanged += OnSelectionChangedInternal;
View.Add += OnAdd;
}
void OnSelectionChangedInternal(TKey selectedValue)
{
this.SelectedValue = selectedValue;
OnSelectionChanged(selectedValue);
}
protected abstract void OnSelectionChanged(TKey selectedVaule);
protected abstract bool OnAdd();
}
// Concrete Views
public interface INotes : IView<Note, string> { }
public interface IAttachments : IView<Attachment, string> { }
// Concrete Presenters
public class NotesPresenter : Presenter<Note, string>
{
public NotesPresenter(INotes view) : base(view) { }
protected override void OnSelectionChanged(string publisherName) { }
protected override bool OnAdd() { return false; }
}
public class AttachmentsPresenter : Presenter<Attachment, string>
{
public AttachmentsPresenter(IAttachments view) : base(view) { }
protected override void OnSelectionChanged(string publisherName) { }
protected override bool OnAdd() { return false; }
}