关注点分离;MVC;为什么?

在开始我的下一个主要项目之前,我目前正在阅读 OO.为了让您快速了解一些背景知识,我是一名 PHP 开发人员,从事 Web 应用程序的工作.

I'm currently reading up on OO before I embark upon my next major project. To give you some quick background, I'm a PHP developer, working on web applications.

我特别感兴趣的一个领域是用户界面;特别是如何构建它并将其连接到我的 OO模型".

One area that particularly interests me is the User Interface; specifically how to build this and connect it to my OO "model".

我一直在阅读这方面的内容.我的最爱之一是这样的:为面向对象系统构建用户界面

I've been doing some reading on this area. One of my favourites is this: Building user interfaces for object-oriented systems

所有对象都必须提供自己的用户界面"

"All objects must provide their own UI"

考虑到我的问题,我可以看到它运行良好.例如,我构建了我的用户"对象来代表登录我网站的人.我的方法之一是display_yourself"或类似方法.我可以在整个代码中使用它.也许一开始就是他们的名字.后来,如果我需要调整显示他们的名字+小头像,我可以只更新这个方法,嘿嘿,我的应用程序更新了.或者,如果我需要将他们的名字作为指向他们个人资料的链接,嘿嘿,我可以从一个地方轻松地再次更新.

Thinking about my problem, I can see this working well. I build my "user" object to represent someone who has logged into my website, for example. One of my methods is then "display_yourself" or similar. I can use this throughout my code. Perhaps to start with this will just be their name. Later, if I need to adjust to show their name+small avatar, I can just update this one method and hey-presto, my app is updated. Or if I need to make their name a link to their profile, hey-presto I can update again easily from one place.

就面向对象系统而言;我认为这种方法效果很好.查看其他 StackOverflow 线程,我在关注点分离"下发现了这一点:社会

In terms of an OO system; I think this approach works well. Looking on other StackOverflow threads, I found this under "Separation of Concerns": Soc

"在计算机科学中,分离关注(SoC)是一个过程将计算机程序分解为重叠的不同特征功能尽量少.一个关注是任何感兴趣或专注于一个程序.通常,关注点是特征的同义词或行为.SoC 的进展是传统上通过模块化和封装性信息隐藏的帮助."

"In computer science, separation of concerns (SoC) is the process of breaking a computer program into distinct features that overlap in functionality as little as possible. A concern is any piece of interest or focus in a program. Typically, concerns are synonymous with features or behaviors. Progress towards SoC is traditionally achieved through modularity and encapsulation, with the help of information hiding."

在我看来,我已经做到了这一点.我的用户对象隐藏了它的所有信息.我的代码中没有任何地方在显示之前说 $user->get_user_name().

To my mind I have achieved this. My user object hides all it's information. I don't have any places in my code where I say $user->get_user_name() before I display it.

然而,这似乎与其他人认为的最佳实践"背道而驰.

However, this seems to go against what other people seem to think of as "best practice".

引用同一问题中的选定"(绿色)答案:

To quote the "selected" (green one) answer from the same question:

"关注点分离是保持每个问题的代码分离.改变界面不应该要求改变业务逻辑代码,反之亦然.模型-视图-控制器 (MVC) 设计模式是一个很好的例子更好地分离这些问题软件可维护性."

"The separation of concerns is keeping the code for each of these concerns separate. Changing the interface should not require changing the business logic code, and vice versa. Model-View-Controller (MVC) design pattern is an excellent example of separating these concerns for better software maintainability."

为什么这会提高软件的可维护性?当然,对于 MVC,我的视图必须非常了解模型?阅读 JavaWorld 文章以详细讨论这一点:为面向对象系统构建用户界面

Why does this make for better software maintainability? Surely with MVC, my View has to know an awful lot about the Model? Read the JavaWorld article for a detailed discussion on this point: Building user interfaces for object-oriented systems

不管怎样……总算说到点子上了!

Anyway... getting to the actual point, finally!

1. 谁能推荐一本详细讨论这个问题的书?我不想要一本 MVC 的书;我不卖 MVC.我想要一本讨论 OO/UI、潜在问题、潜在解决方案等的书.(可能包括 MVC)Arthur Riel 的面向对象的设计启发式

1. Can anyone recommend any books that discuss this in detail? I don't want an MVC book; I'm not sold on MVC. I want a book that discusses OO / UI, the potential issues, potential solutuions etc.. (maybe including MVC) Arthur Riel's Object-Oriented Design Heuristics

触及它(也是一本很棒的书!),但我想要更详细的东西.

touches on it (and is an excellent book as well!), but I want something that goes into more detail.

2. 谁能提出一个像 Allen Holub 的 JavaWorld 文章那样解释清楚的论点,解释为什么 MVC 是一个好主意?

2. Can anyone put forward an argument that is as well-explained as Allen Holub's JavaWorld article that explains why MVC is a good idea?

非常感谢任何能帮助我得出结论的人.

Many thanks for anyone who can help me reach a conclusion on this.

推荐答案

这是 OOP 教学经常失败的地方,使用了像 rectangle.draw() 和恐龙.show() 这样的例子,这些例子完全没有意义.

This is a failure in how OOP is often taught, using examples like rectangle.draw() and dinosaur.show() that make absolutely no sense.

当您谈论拥有显示自身的用户类时,您几乎是在回答自己的问题.

You're almost answering your own question when you talk about having a user class that displays itself.

以后,如果我需要调整显示他们的名字+小头像,我可以只更新这一种方法,嘿嘿,我的应用程序更新了."

"Later, if I need to adjust to show their name+small avatar, I can just update this one method and hey-presto, my app is updated."

暂时只考虑那一小块.现在看看 Stack Overflow 并注意您的用户名出现的所有位置.在每种情况下看起来都一样吗?不,在顶部,您的用户名旁边有一个信封,后面是您的声誉和徽章.在一个问题线程中,您的头像后面是您的用户名,下面是您的声誉和徽章.你认为有一个用户对象有像 getUserNameWithAvatarInFrontOfItAndReputationAndBadgesUnderneath() 这样的方法吗?不.

Think about just that little piece for moment. Now take a look at Stack Overflow and notice all of the places that your username appears. Does it look the same in each case? No, at the top you've just got an envelope next to your username followed by your reputation and badges. In a question thread you've got your avatar followed by your username with your reputation and badges below it. Do you think that there is a user object with methods like getUserNameWithAvatarInFrontOfItAndReputationAndBadgesUnderneath() ? Nah.

一个对象与它所代表的数据和作用于该数据的方法有关.您的用户对象可能具有 firstName 和 lastName 成员,以及检索这些部分所需的 getter.它也可能有一个像 toString()(在 Java 术语中)这样的便捷方法,它会以一种通用格式返回用户名,比如名字后跟一个空格,然后是姓氏.除此之外,用户对象不应该做太多其他事情.由客户决定要对对象做什么.

An object is concerned with the data it represents and methods that act on that data. Your user object will probably have firstName and lastName members, and the necessary getters to retrieve those pieces. It might also have a convenience method like toString() (in Java terms) that would return the user's name in a common format, like the first name followed by a space and then the last name. Aside from that, the user object shouldn't do much else. It is up to the client to decide what it wants to do with the object.

以您为我们提供的用户对象为例,然后考虑如果您在其中构建了UI",您将如何执行以下操作:

Take the example that you've given us with the user object, and then think about how you would do the following if you built a "UI" into it:

  1. 创建显示所有用户的 CSV 导出,按姓氏排序.例如.姓氏,名字.
  2. 提供重量级的 GUI 和基于 Web 的界面来处理用户对象.
  3. 在一处显示用户名旁边的头像,而在另一处仅显示用户名.
  4. 提供用户的 RSS 列表.
  5. 在一处显示用户名粗体,在另一处显示为斜体,并在另一处显示为超链接.
  6. 在适当的地方显示用户的中间名首字母.

如果你考虑一下这些需求,它们都归结为提供一个用户对象,它只关心它应该关心的数据.它不应该试图对每个人都适用,它应该只是提供一种获取用户数据的方法.您将创建的多个视图中的每一个都决定如何显示用户数据.

If you think about these requirements, they all boil down to providing a user object that is only concerned with the data that it should be concerned with. It shouldn't try to be all things to everyone, it should just provide a means to get at user data. It is up to each of the many views you will create to decide how it wants to display the user data.

您关于在一处更新代码以在多处更新您的视图的想法是个好主意.这仍然是可能的,而无需在太低的水平上搞砸.您当然可以创建类似小部件的类来封装东西"的各种常见视图,并在整个视图代码中使用它们.

Your idea about updating code in one place to update your views in many places is a good one. This is still possible without mucking with things at a too low of a level. You could certainly create widget-like classes that would encapsulate your various common views of "stuff", and use them throughout your view code.

相关文章