B2 · 第7集 · 4:56

JavaFX音乐播放器架构

讲解JavaFX音乐播放器的MVC设计模式,包括模型(数据与逻辑)、视图(界面)和控制器(二者通信)的职责划分。

来源:Nicolas Hurtubise / classe.iro.umontreal.ca · 许可:CC BY-SA 4.0

字幕

  1. On aurait là- dedans des informations reliées à une chanson en particulier,

    这里面会包含与某首特定歌曲相关的信息,

  2. par exemple le titre, l'album, la durée, l'image de la pochette,

    比如歌名、所属专辑、时长、封面图片,

  3. le fichier qui est associé à ça.

    以及关联的音频文件。

  4. Ça contiendrait aussi l'état de la chanson qui est en train d'être jouée,

    它还会包含当前正在播放的歌曲的状态,

  5. mettons. Combien de temps qui

    比如说,还剩多少时间,

  6. reste, est- ce qu'on est en mode play, est- ce qu'on est en mode pause,

    当前是播放模式还是暂停模式,

  7. tout ça. On pourrait avoir une classe générale

    诸如此类。我们可以设计一个通用类,

  8. qui représente notre lecteur de musique,

    来代表我们的音乐播放器,

  9. ça contiendrait par exemple une playlist, ça contiendrait la chanson actuelle,

    例如,它包含一个播放列表和当前播放的歌曲,

  10. puis ça définirait dans le fond toutes les actions abstraites.

    并定义所有抽象的操作。

  11. Pour qu'est- ce qu'on peut faire pour modifier l'état du lecteur de musique.

    也就是:我们能执行哪些操作来改变播放器的状态?

  12. Par exemple, passer à la prochaine chanson,

    比如,切换到下一首歌,

  13. ajouter une chanson dans la playlist, mettre la chanson

    向播放列表添加一首歌,

  14. actuellement en pause, télécharger la pochette, toutes ces choses- là,

    将当前歌曲设为暂停,下载封面图片,等等这些功能,

  15. ça irait dans le modèle.

    都属于模型部分。

  16. Vraiment toutes ces choses- là,

    实际上,所有这些功能,

  17. c'est quelque chose qui pourrait exister sans l'interface graphique

    即使没有图形界面也能独立存在,

  18. et qui résoudrait quand même notre problème.

    同时依然能解决我们的实际问题。

  19. Comme je l'ai mentionné, le contrôleur c'est ce qui va relier les deux.

    正如我之前提到的,控制器负责连接这两部分。

  20. Dans le fond, quand on clique sur un bouton,

    本质上,当我们点击一个按钮时,

  21. quand on clique sur un bouton dans l'interface,

    当我们点击界面上的某个按钮时,

  22. il faut que le contrôleur soit visé, puis à ce moment- là,

    控制器必须被触发,此时,

  23. les méthodes dans le modèle vont être appelées.

    模型中的方法就会被调用。

  24. Quand on clique sur le bouton Next, au

    当我们点击‘下一首’按钮时,

  25. niveau du modèle, il faudrait que la playlist passe

    在模型层面,播放列表需要切换到下一首歌,

  26. à la prochaine chanson.

    这就是它的作用。

  27. Quand on clique sur pause, il faut que la chanson actuelle soit mise en pause.

    点击暂停时,

  28. Puis inversement, quand le modèle est modifié,

    反之,当模型发生变化时,

  29. il faut que le contrôleur soit avisé pour dire à la vue de se mettre à jour.

    控制器必须收到通知,以便告知视图更新自身。

  30. Dans le fond, quand il y a une chanson qui termine,

    实际上,当一首歌曲播放结束时,

  31. on passe automatiquement à la prochaine chanson.

    系统会自动切换到下一首歌曲。

  32. Il faut changer la pochette d'album qui est affichée,

    需要更换当前显示的专辑封面,

  33. le titre de la chanson qui est affiché, tout ça.

    以及正在显示的歌曲标题等所有内容。

  34. Donc, ça va dans les deux sens.

    因此,这种交互是双向的。

  35. Le contrôleur ne devrait vraiment avoir aucune autre logique que celle qui va faire

    控制器本身不应包含任何其他逻辑,

  36. la communication entre la vue et le modèle.

    只应负责视图与模型之间的通信。

  37. Fait que la décomposition MVC nous offre un assez gros avantage par rapport à tout

    因此,MVC 分层结构相比把所有代码都塞进 start 函数中,

  38. mettre dans la fonction start, surtout au niveau de la maintenabilité du code.

    尤其在代码可维护性方面。

  39. Si vous voyez qu'il y a un bug au niveau de l'affichage,

    如果你发现显示有问题,

  40. ben vous savez tout de suite que vous avez besoin d'aller chercher l'erreur au

    你马上就知道应该去查看

  41. niveau des classes reliées à la vue.

    与视图相关的那些类。

  42. S'il y a un problème de logique,

    如果出现逻辑问题,

  43. ben vous savez tout de suite que vous devez chercher seulement dans les classes

    你立刻明白只需检查

  44. reliées au modèle.

    与模型相关的类。

  45. Puis au niveau des tests unitaires, une

    此外,在单元测试层面,

  46. application graphique est très difficile à tester.

    图形界面应用程序非常难以测试。

  47. Dans le fond, si toute votre logique dépend du bouton,

    实际上,如果全部逻辑都依赖于按钮,

  48. puis dépend de la présence ou du clic dans un bouton.

    比如依赖按钮是否存在或是否被点击,

  49. ça devient très difficile d'écrire des tests,

    编写测试就会变得极其困难;

  50. vous commencez à devoir trouver des façons weird de simuler des clics dans

    你不得不开始寻找各种奇怪的方法,

  51. l'interface. C'est vraiment pas très pratique.

    来模拟界面上的点击操作——这真的非常不方便。

  52. En MVC en particulier, le modèle va être indépendant de la vue,

    在MVC架构中,尤其是模型部分将独立于视图,

  53. ce qui veut dire qu'on peut écrire des tests pour notre modèle exactement comme on

    这意味着我们可以像测试纯命令行代码一样,

  54. le ferait dans le cas où on aurait du code complètement en ligne de commande.

    为模型编写测试。

  55. Ok, j'aimerais ça revenir sur à quoi sert le contrôleur.

    好的,我想再讲一讲控制器的作用。

  56. Donc généralement quand j'explique le concept de modèle vue contrôleur,

    通常,当我讲解MVC(模型-视图-控制器)概念时,

  57. le modèle ça va assez bien, le modèle c'est assez clair,

    模型这部分大家理解得比较顺畅,

  58. c'est la logique du code, c'est les fonctions qui servent à faire la

    它代表程序的核心逻辑,也就是实现业务功能的函数,

  59. logique, c'est aussi les

    同时也包括数据本身。

  60. données. La vue c'est assez clair, la vue c'est la définition de l'interface.

    视图也很明确,就是用户界面的定义。

  61. Le contrôleur peut sembler

    而控制器则可能显得

  62. un peu plus flou ou un peu redondant.

    有点模糊,甚至略显多余。

  63. Dans le fond, la question c'est pourquoi est- ce qu'on pourrait pas avoir seulement

    归根结底,问题在于:

  64. une structure vue modèle?

    一个只有视图和模型的结构?

  65. Pourquoi est- ce qu'on pourrait pas seulement avoir la vue qui

    为什么不能让视图直接创建模型呢?

  66. crée le modèle?

    (为什么不能)仅此而已?

  67. Quand il y a quelque chose qui se passe dans la vue,

    当视图中发生某些事件时,

  68. il faut avertir le modèle. Quand il y a quelque chose dans le modèle qui se passe,

    需要通知模型;当模型中发生某些变化时,

  69. il faut avertir la vue.

    又需要通知视图。

  70. Pourquoi est- ce qu'on a besoin d'un contrôleur qui fait le pont entre les deux?

    那为什么还需要一个在两者之间起桥梁作用的控制器呢?

  71. Puis la réponse à ça, c'est que la présence du contrôleur,

    这个问题的答案是:控制器的存在,

  72. c'est ce qui permet vraiment d'isoler le modèle de la vue.

    真正实现了模型与视图的隔离。

  73. Ce qui permet vraiment de faire en sorte que la vue a pas besoin de connaître le

    这确保了视图无需了解模型即可独立存在,

  74. modèle pour exister, puis

    同时,

  75. le modèle a pas besoin de

    模型也无需了解视图,

  76. connaître la vue pour exister.

    就能独立运行。

  77. Et ça, ça a des avantages assez intéressants,

    而这具有一些相当有趣的优势,

  78. entre autres le fait qu'on peut réutiliser un même modèle avec différentes vues.

    例如,同一个模型可适配多种界面。

  79. Ici, vous avez une screenshot du encore le lecteur de musique VLC,

    这里展示的是 VLC 音乐播放器的截图,

  80. donc le même que tout à l'heure,

    也就是刚才提到的同一款软件,

  81. qui possède aussi une interface en ligne de commande.

    它也支持命令行界面。

  82. Donc plutôt que d'afficher la playlist de

    因此,无需以图形方式显示播放列表,

  83. façon graphique, puis d'afficher le titre du fichier puis

    再以图形界面显示当前文件标题,

  84. tout ça en interface graphique,

    以及所有其他图形化内容,

  85. On a exactement le même modèle, on a exactement la même application,

    我们使用完全相同的模型和应用程序,

  86. la même logique, mais avec une interface codée dans une autre librairie

    逻辑也完全一致,

  87. complètement, dans une librairie qui permet d'afficher des choses en ligne de

    只是界面改用另一套专用于命令行显示的库来实现。

  88. commande. L'inverse est également vrai.

    反过来也同样可行。

  89. Ça devrait être possible de réutiliser une même vue pour afficher différents

    理论上,同一套界面也可用于展示不同模型,

  90. modèles, dans la mesure où les modèles sont compatibles entre eux bien sûr.

    前提是这些模型彼此兼容。

  91. On a un bel exemple de ça avec le

    GNOME 桌面环境中的纸牌游戏,

  92. programme. Ce programme- là, ce petit jeu de cartes- là de Gnome qui

    这款小巧的 GNOME 纸牌游戏,

  93. est disponible sur Linux.

    在 Linux 系统上即可使用。