使用 MVP 模式和 OO 原则
Posted
技术标签:
【中文标题】使用 MVP 模式和 OO 原则【英文标题】:Using the MVP pattern and OO principles 【发布时间】:2012-01-07 19:01:05 【问题描述】:我正在尝试在使用 MVP 模式的场景中应用面向对象编程的原则。 我有 4 个解决方案,最后两个我更喜欢。 然而,大多数解决方案都分解了某些原则,如 SRP、IOC / DIP、开闭原则等。
简而言之,我希望查看者和演示者可以有一个可选的行为。此行为允许查看器拥有一个窗口或包含在一个面板中。 在我看来,查看者应该了解 JFrame 和侦听器,当查看者支持所选的窗口行为时,窗口演示者应该执行一些额外的操作。
您能帮我找到适合这种情况的最佳设计吗?我相信这些例子会说明需要。
解决方案 1 - 类似适配器
public class Main
public static void main(String[] args)
ConcreteWindowedView view = new ConcreteWindowedView();
Presentable presenter = new ConcreteWindowedPresenter(view);
presenter.present();
public interface Presentable
public void present();
public interface Viewable
public void view();
public class ConcreteView implements Viewable
private Container container;
public ConcreteView(Container container)
this.container = container;
public void view()
// Configure UI (TextBox, Buttons) inside container;
public class ConcretePresenter implements Presentable
private Viewable viewable;
public ConcretePresenter(Viewable viewable)
this.viewable = viewable;
public void present()
// Configure presenter;
viewable.view();
// Register UI action listener
public class ConcreteWindowedView implements Viewable
private ConcreteView contentView;
private JFrame frame;
public ConcreteWindowedView()
frame = new JFrame();
contentView = new ConcreteView(frame.getContentPane());
public void view()
contentView.view();
public void addWindowListerner()
public class ConcreteWindowedPresenter implements Presentable
private ConcreteWindowedView windowedView;
private ConcretePresenter concretePresenter;
public ConcreteWindowedPresenter(ConcreteWindowedView windowedView)
this.windowedView = windowedView;
this.concretePresenter = new ConcretePresenter(windowedView);
public void present()
// Configure presenter
concretePresenter.present();
// Register window listeners
this.windowedView.addWindowListerner();
解决方案 2 - 使用继承
public class Main
public static void main(String[] args)
ConcreteWindowedView view = new ConcreteWindowedView();
Presentable presenter = new ConcreteWindowedPresenter(view);
presenter.present();
public interface Viewable
public void view();
public interface Presentable
public void present();
public class ConcreteView implements Viewable
protected Container container;
protected ConcreteView()
public ConcreteView(Container container)
this.container = container;
public void view()
// Configure UI (TextBox, Buttons) inside container;
public class ConcreteWindowedView extends ConcreteView
public JFrame frame;
public ConcreteWindowedView()
frame = new JFrame();
container = frame.getContentPane();
public void view()
// Configure view
super.view();
// Show JFrame
public void addWindowListerner()
public class ConcretePresenter implements Presentable
Viewable viewable;
public ConcretePresenter(Viewable viewable)
this.viewable = viewable;
public void present()
// Configure presenter;
viewable.view();
// Register UI action listener
public class ConcreteWindowedPresenter extends ConcretePresenter
private ConcreteWindowedView concreteWindowedView;
public ConcreteWindowedPresenter(ConcreteWindowedView viewable)
super(viewable);
this.concreteWindowedView = viewable;
public void present()
// Configure presenter
super.present();
// Register window listeners
this.concreteWindowedView.addWindowListerner();
解决方案 3 - 使用窗口处理程序
public class Main
public static void main(String[] args)
Viewable view = new ConcreteView();
Presentable presenter = new ConcretePresenter(view, new WindowViewHandler(view));
presenter.present();
public interface Viewable
public void view();
public void setContainer(Container container);
public interface Presentable
public void present();
public class ConcreteView implements Viewable
Container container;
public ConcreteView()
public ConcreteView(Container container)
this.container = container;
public void view()
if (container == null)
throw new RuntimeException("Container not set.");
// Configure UI (TextBox, Buttons) inside container;
public void setContainer(Container container)
this.container = container;
public class ConcretePresenter implements Presentable
Viewable viewable;
WindowViewHandler windowHandler;
public ConcretePresenter(Viewable viewable)
this.viewable = viewable;
public ConcretePresenter(Viewable viewable, WindowViewHandler windowHandler)
this(viewable);
this.windowHandler = windowHandler;
public void present()
// Configure presenter
if (windowHandler != null)
windowHandler.addWindowListerner();
this.viewable.view();
public class WindowViewHandler
Viewable viewable;
JFrame frame;
public WindowViewHandler(Viewable viewable)
this.viewable = viewable;
initWindow();
private void initWindow()
frame = new JFrame();
viewable.setContainer(frame.getContentPane());
public void addWindowListerner()
解决方案 4
public class Main
public static void main(String[] args)
ConcreteWindowedView view = new ConcreteWindowedView();
Presentable presenter = new ConcretePresenter(view);
presenter.present();
public interface Windowable
public void addWindowListerner();
public interface Viewable
public void view();
public void setContainer(Container container);
public interface Presentable
public void present();
public class ConcreteView implements Viewable
Container container;
public ConcreteView()
public void setContainer(Container container)
this.container = container;
public void view()
if (container == null)
throw new RuntimeException("Container not set.");
public class ConcreteWindowedView extends ConcreteView implements Windowable
JFrame frame;
public ConcreteWindowedView()
public void view()
frame = new JFrame();
super.setContainer(frame.getContentPane());
super.view();
public void addWindowListerner()
public class ConcretePresenter implements Presentable
Viewable viewable;
ConcreteWindowedView concreteWindowedView;
public ConcretePresenter(Viewable viewable)
this.viewable = viewable;
public ConcretePresenter(ConcreteWindowedView concreteWindowedView)
this.viewable = concreteWindowedView;
this.concreteWindowedView = concreteWindowedView;
public void present()
// Configure presenter
if (concreteWindowedView != null)
concreteWindowedView.addWindowListerner();
this.viewable.view();
谢谢
【问题讨论】:
在提出解决方案之前,了解问题所在会有所帮助。你能解释一下你想解决什么问题,而不是让我们通过阅读 4 个长代码块来猜测它是什么? 我改进了这个问题。 太抽象了,需要更实际一点 替代方案需要维护一些状态,MVP 中的一个大“问题”是确定谁“拥有”状态,以及谁“更新”状态、演示者或视图。因此,您可能想为该窗口添加一个状态,只需一些具有属性的简单对象就足够了。您的示例缺少 MVP 中的 M(odel)。 Regarding open-closed principle, “没有重要的程序可以 100% 关闭”和“由于关闭不能完全,它必须是战略性的。也就是说,设计者必须选择改变的种类,以应对关闭他的设计。”如果您要担心 OCP,您希望将您的设计与哪些更改隔离开来?通常,MV* 中的视图比模型的元素更频繁地更改。因此,策略旨在使模型远离视图的开放性。 【参考方案1】:解决方案 1 更多的是关于组合而不是适配器。 更喜欢解决方案 1 而不是解决方案 2,因为组合比继承更灵活。
【讨论】:
以上是关于使用 MVP 模式和 OO 原则的主要内容,如果未能解决你的问题,请参考以下文章