使用 MVP 模式和 OO 原则

发布于 2024-12-25 11:22:55 字数 7753 浏览 4 评论 0原文

我尝试在使用 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();     
    }           
}

谢谢您

I'm trying to apply the principles of object-oriented programming in a scenario that uses the MVP pattern.
I got 4 solutions, and the last two I liked more.
However most of the solutions break down certain principles as SRP, IOC / DIP, Open-Closed Principle, etc..

Briefly, I want the viewer and the presenter may have an optional behavior. This behavior allows the viewer to has a window or to be contained in one panel.
In my opinion the viewer should have knowledge of the JFrame and listeners, the windowed presenter should perform some additional actions when the viewer supports the chosen window behavior.

Can you help me find the best design for this situation? I believe that the examples will make clear the need.

Solution 1 - Adapter like

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();
    }
}

Solution 2 - Using inheritance

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();
    }
}

Solution 3 - Using a window handler

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() {
    }
}

Solution 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();     
    }           
}

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2025-01-01 11:22:56

解决方案 1 更多的是关于组合而不是适配器。
与解决方案 2 相比,更喜欢解决方案 1,因为组合比继承更灵活。

Solution 1 is more about composition rather than adapter.
prefer Solution 1 over Solution 2 since composition is more flexible than inheritance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文