Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:MVC和控制器的匿名类_Java_Model View Controller - Fatal编程技术网

Java:MVC和控制器的匿名类

Java:MVC和控制器的匿名类,java,model-view-controller,Java,Model View Controller,我有一个关于MVC模式的问题。我正试图使用IntelliJ IDEA中的Java将其用于桌面项目(即不用于网络应用程序)。 我试图根据MVC模式创建模型、视图和控制器。我的问题是:从Java的角度来看,标记的方法已经作为控制器使用了,实际上不需要创建一个显式的控制器类作为单独的类,这样说安全吗?像这样: 或者我必须创建一个显式CalculatorController类,如下所示: 请记住,我的任务是保持MVC模式,其中M、V和C的任务是明确划分的。 在这两个选项中,哪一个保留MVC模式?只有

我有一个关于MVC模式的问题。我正试图使用IntelliJ IDEA中的Java将其用于桌面项目(即不用于网络应用程序)。 我试图根据MVC模式创建模型、视图和控制器。我的问题是:从Java的角度来看,标记的方法已经作为控制器使用了,实际上不需要创建一个显式的控制器类作为单独的类,这样说安全吗?像这样:

或者我必须创建一个显式CalculatorController类,如下所示:

请记住,我的任务是保持MVC模式,其中M、V和C的任务是明确划分的。 在这两个选项中,哪一个保留MVC模式?只有第二个,或者两者都相等?
谢谢大家!

第二选项

如果您将控制器用作匿名内部类,您将如何测试控制器层?如果你不分离你的控制器,你将无法模拟测试目的

即使您不想编写测试,第一个选项将在视图和控制器之间创建真正的硬耦合。根本没有分离

更愿意在实现之前显式地创建控制器并为其创建接口。它将使TDD变得更容易,并且您还将在项目中进行更好的代码设计

但请记住,这只是我的意见。始终学习,以确保您的项目决策是正确的,并为您工作

在本文中,它有一个非常简单的模式实现:

编辑

让我们比较两种方法。

  • 可测试性
  • 内部类:无法测试控制层。所有控制器都是匿名内部类。因此,您无法访问,因此无法进行测试。在MCV架构中,测试控制器非常重要。结论:对测试来说真的很糟糕

    显式类:可以模拟视图和模型,以便测试控制器。在测试视图和模型时也会使用相同的逻辑。结论:易于测试

  • 维修性
  • 内部类:所有控制器逻辑都在匿名内部类(或lambda)中。相信我,你不会想要的。你的应用程序的所有复杂性都在一个原本不打算变大的类中。一个简单的例子:

    //I need to get the people older than 50 years old, present to the user and wait for a click. If the list is empty, do something, if it's not do something else.
    
          buttonRefresh.onClickListener(() -> {
              List<Person> people = model.requestPeople();
    
              people = people.stream()
                          .filter(p -> p.getAge > 50) 
                          .collect(Collectors.toList())
    
              [code to create an adapter]
    
              if(people.isEmpty()){
                 [do something...]
              } else{
                 [do something else...]
              }
    
          })
    
    //我需要让50岁以上的人出现在用户面前,等待点击。如果列表是空的,做点什么,如果没有,做点别的。
    按钮刷新。onClickListener(()->{
    List people=model.requestPeople();
    people=people.stream()
    .filter(p->p.getAge>50)
    .collect(收集器.toList())
    [创建适配器的代码]
    if(people.isEmpty()){
    [做点什么…]
    }否则{
    [做点别的…]
    }
    })
    
    这是一个非常简单的代码,它已经变得令人困惑。如果我的if和else里还有一个lambda呢??匿名内部类中的代码越大,情况就越糟。结论:这不利于可维护性,因为您的代码将在错误的地方增长

    显式类:代码可以在类中增长。您可以在那里添加依赖项,创建方法,创建内部类

  • 责任分离
  • 内部类:事实上,没有控制器层。所有控制器代码都在视图类中,因此视图和控制器以及基本相同的类。因此,您将拥有一个非常庞大的视图类,其中包含大量混乱的代码。结论:糟糕,应用程序的几乎所有代码都将在视图类中

    显式类:控制器和视图有非常清晰的分离。您的视图将只有更新视图的方法

    (我知道您将要创建很多方法,在视图类中基本上有1-3行代码。但这比在同一位置使用视图和控制逻辑的大型方法要好。)


    这就是我的想法。但您可以尝试这两种方法并比较结果

    MVC的要点是将M与V分开,并与C分开-如果你将它们结合在一起,你就错过了让你的C可以被多个V访问的一个巨大优势(即稍后使用GUI和WEB GUI的JFrame)@ochi谢谢!好的,到目前为止,我对每个视图都有一个单独的控制器(那么称它为Presenter可能是正确的吗?)并且不打算对多个VS使用一个C。我再次查看图像,您是否认为
    actionListeners
    控制器?@ochi似乎就是这样。通过V和C之间的“显式”划分,控制器是侦听器向其发送请求(或信息)的对象,如第二张图所示:侦听器调用控制器通知其按钮被按下,控制器调用模型相应地操作数据。在第一幅图中,监听器调用Model而不在它们之间,因此在某种意义上,监听器是一种控制器,它是一个独立的类(只是匿名的,但仍然是独立的,如MVC模式所示)。嗯,至少我是这样理解的。把监听器和控制器分开可以给你灵活性。今天,您可能正在与连接到DB的后端进行对话。明天,您的数据可能来自REST服务(一个文件或其他数据源)-如果您将所有获取的数据放在侦听器中(假装它是一个控制器,实际上不是),那么当后端发生更改时,您需要更改所有侦听器(大量重复工作)-相反,如果您的控制器更改了后端(并且您正在使用接口)您只需更改