【问题标题】:Good MVC design for calling a method by many classes良好的 MVC 设计,用于由许多类调用方法
【发布时间】:2013-05-06 08:37:33
【问题描述】:

编辑(16.05.2013):

我将使用我的第三个解决方案。谢谢大家的帮助。

编辑结束(16.05.2013)

我有一个带有更新方法的视图(在控制器内)。该方法必须由许多类调用。所以我想出了两个解决方案:

  1. 在每个需要调用更新方法的类中为视图/控制器创建一个字段。
  2. 将更新方法设为静态。

什么是更好的 (M)VC 设计?如果两个或多个类同时调用更新方法会发生什么?

简化示例 1:

public class View{
    public void update(){}
}

// Many classes:
public class AClass{
    private View view;

    private void aMethod(){
        view.update();
    }
}

简化示例 2:

public class View{
    public static void update(){}
}

// Many classes:
public class AClass{

    private void aMethod(){
        View.update();
    }
}

编辑(12.05.2013):我同意,“静态解决方案”不好,尤其是对于 OOP。

我稍微简化了一点,所以这是实际的设计:

假设您有一些 MVC 设计的程序并希望将它们放在一个“大”程序中,但现在这些程序必须不时交互。

public class AView{
    public void update(){}
}

public class AModel{}

//Many of these:
public class AController{
    private AView aview;
    private AModel amodel;

    public AController(AView aview, AModel amodel){
        this.aview=aview;
        this.amodel=amodel;
    }
}

public class MainController{
    public MainController(){
        AView view1 = new AView();
        AModel model1 = new AModel();
        AController controller1 = new AController(view1, model1);

        AView view2 = new AView();
        AModel model2 = new AModel();
        AController controller2 = new AController(view2, model2);

        AView view3 = new AView();
        AModel model3 = new AModel();
        AController controller3 = new AController(view3, model3);
    }
}

现在假设controller1和controller2需要调用view3的update方法。 我目前的解决方案是在控制器 1 和控制器 2 中创建一个视野 3(如您所建议的那样)。

AController controller1 = new AController(view1, view3, model1);
AController controller2 = new AController(view2, view3, model2);

或者我应该重构整个设计还是在控制器之间建立一个“桥梁”?那座“桥”会是什么样子?

编辑结束 (12.05.2013)

编辑(14.05.2013): 我想出了第三种解决方案: 每个控制器都会触发它自己的事件。例如:

Controller1 和 Controller2 触发事件,Controller3 监听它们然后调用 View3 的更新方法。 您如何看待这个解决方案?

编辑结束 (14.05.2013)

【问题讨论】:

  • 这一切都取决于你是否需要View的内部状态。如果将其设为静态,则需要将整个状态设为静态 - 这显然是代码异味。如果您不需要状态,那么每个类都应该有自己的View 实例。如果您需要共享状态,那么您需要回答自己的问题“如果两个或多个类同时调用更新方法会发生什么”,然后再决定如何共享类的实例。

标签: java model-view-controller


【解决方案1】:

扔掉静态解决方案,甚至不要考虑这一点,因为这样做会将所有 OOP 扔出窗外。给控件一个公共的update() 方法,如果需要,该方法调用视图的方法。

话虽如此,但您的问题让我担心紧耦合。

这些需要调用视图更新的其他类——它们是控制类/库的一部分吗?只有控件应该在视图上调用更新。


编辑,你说:

您能否详细解释一下“静态方法将所有 OOP 抛出窗外”,我很想知道这一点。

当你将一个方法设为静态时,它不再是可继承的,更重要的是,它不再是类实例的方法,而是类对象的方法。因此,单独的实例将不再有自己独特的方法可以调用,它不能从实例中获取状态数据,也不能改变实例的状态。

【讨论】:

  • 您能否详细解释一下“静态方法将所有 OOP 抛出窗外”,我很想知道这一点。所以请。
【解决方案2】:

我希望整个模型会更新同一个视图,并为各种数据保持更新。

public class View{
     private View(){}
     public void update(){}
     private static class singleTonFactory{
          private Static View obj = new View();
     }

     public static View getViewInstance (){
          return singleTonFactory.obj;
     }
}


 // Many classes:
public class AClass{
     private final View view = View.getViewInstance();

     private void aMethod(){
          view.update();
     }
 }

【讨论】:

    【解决方案3】:

    我将使用以下设计,因为它将是模块化的(感谢@Hovercraft Full Of Eels 指出紧密耦合):

    public class MainController{
    
        private Controller1 controller1;
        private Controller2 controller2;
        private Controller3 controller3;
    
        public MainController(){
            controller1=new Controller1();            
            controller2=new Controller2();           
            controller3=new Controller3();
    
            addListeners();
        }
    
        private class Ctrl1Listener implements Controller1Listener(){        
            public void controller1ActionPerformed(Controller1Event e){
                //Calls the method of view3     
                controller3.update();
            }
        }
    
        private class Ctrl2Listener implements Controller2Listener(){           
            public void controller2ActionPerformed(Controller2Event e){
                //Calls the method of view3     
                controller3.update();
            }
        }
    
        private void addListeners(){
            controller1.addListener(new Ctrl1Listener());
            controller2.addListener(new Ctrl2Listener());
        }
    }
    

    非常感谢您的评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多