如何向某人解释数据结构不应该绘制自身,解释关注点分离?
我有另一位程序员,我试图向他解释为什么 UI 组件不应该也是一种数据结构。
例如,假设您获得一个包含来自“数据库”的记录集的数据结构,并且您希望在应用程序内的 UI 组件中显示该记录集。
根据这位程序员(他将保持匿名,他很年轻,我正在教他......),我们应该将数据结构子类化为一个类,该类将在我们的应用程序中绘制 UI 组件!
因此根据这个逻辑,记录集应该管理 UI 的绘制。
******Head Desk*****
我知道要求记录集自行绘制是错误的,因为,如果您希望在 UI 上的多种类型的组件上呈现相同的数据结构,你的手上将会出现真正的混乱;您需要为从记录集的基类呈现的每个 UI 组件扩展另一个类;
我很清楚 MVC 模式的“清洁性”(我真正的意思是,不要将数据(模型)与 UI(视图)或在 MVC 上发生的操作混淆)数据(控制器或多或少...好吧,API 不应该真正处理这个...并且控制器应该尽可能少地调用它,告诉它要渲染哪个视图))但它肯定更干净而不是使用数据结构来渲染 UI 组件!
除了上面的例子之外,我还有其他建议可以发送给他吗?我知道,当你第一次学习 OOP 时,你会经历一个“阶段”,在这个阶段你只想扩展一切。
接下来的一个阶段是,您认为设计模式可以解决每个问题……这也不完全正确……谢谢杰夫。
有什么办法可以轻轻地将这个孩子推向正确的方向吗?你还有更多的例子可以帮助向他解释我的观点吗?
I have another programmer who I'm trying to explain why it is that a UI component should not also be a data-structure.
For instance say that you get a data-structure that contains a record-set from the "database", and you wish to display that record-set in a UI component within your application.
According to this programmer (who will remain nameless, he's young and I'm teaching him...), we should subclass the data-structure into a class that will draw the UI component within our application!!!!!!
And thus according to this logic, the record-set should manage the drawing of the UI.
******Head Desk*****
I know that asking a record-set to draw itself is wrong, because, if you wish to render the same data-structure on more than one type of component on your UI, you are going to have a real mess on your hands; you'll need to extend yet another class for each and every UI component that you render from the base-class of your record-set;
I am well aware of the "cleanliness" of the of the MVC pattern (and by that what I really mean is you don't confuse your data (the Model) with your UI (the view) or the actions that take place on the data (the Controller more or less...okay not really the API should really handle that...and the Controller should just make as few calls to it as it can, telling it which view to render)) But it's certainly alot cleaner than using data-structures to render UI components!
Is there any other advice I could send his way other than the example above? I understand that when you first learn OOP you go through "a stage" where you where just want to extend everything.
Followed by a stage when you think that Design Patterns are the solution every single problem...which isn't entirely correct either...thanks Jeff.
Is there a way that I can gently nudge this kid in the right direction? Do you have any more examples that might help explain my point to him?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你听说过马丁·福勒吗?
分离用户界面
无论如何
,如果他想进一步向数据控件添加渲染方法,请让他看看“松散耦合”。创建一些通用类型的界面可以让他完成一半,但 UI 组件应该完成剩下的部分。
Have you heard of Martin Fowler?
Separating User Interface
Code
Anyway, if he wants to go further in that direction of adding render methods to his data controls, have him look at "loose coupling". It's okay to create some generic type of interface that gets him halfway there, but the UI component should take it the rest of the way.
这可以归结为功能性责任与非功能性责任。数据结构的作用和它的可视化方式是两个完全独立的事情——本质上是 MVC 模式的根源。
这里还有一个循环依赖的概念。由于 UI 必须了解数据结构,因此如果您允许数据结构依赖于 UI,那么您就得到了一个漂亮的小泥球。
This boils down to functional vs. non-functional responsibilities. What the data structure does and how it's visualized are two completely separate things -- essentially the root of the MVC pattern.
There's also a notion of circular dependencies here. Since the UI must know about the data structures, if you allow the data structures to then depend on the UI, you've got yourself a nice little ball of mud.
一般来说,关于解耦:
不仅可以有不同的 UI 组件呈现相同的数据结构。您甚至可能拥有完全不同的 UI(Web、桌面应用程序等)现在当然,您可以使用
WebPerson
和DesktopPerson
子类化Person
(这听起来已经不对了,不是吗?命名与 Person 的类型无关 - 它与其他东西有关)。每个 UI 都可以适用于不同类型的人员,例如
Teacher
和Student
。所以我们得到了WebPerson
、WebTeacher
、WebStudent
、DesktopPerson
、DesktopTeacher
和>DesktopStudent
。现在假设,
WebPerson
定义了方法“drawAddressFields()”来绘制网络版本的地址字段。但由于WebTeacher
必须从Teacher
派生才能使用附加数据字段“salary”(假设单继承),因此它必须再次实现“drawAddressFields()”!因此,也许“这将导致更多工作”的论点将有助于创造一些动力:-)
顺便说一句,它将自动导致创建一些实现drawAddressField()代码的委托,然后该委托将演变为创建独立于数据结构进行绘图的组件。
Generally on the point of decoupling:
Not only can there be different components of the UI rendering the same data structure. You may even have completely different UIs (Web, Desktop Application, ...) Now of course, you could subclass
Person
withWebPerson
andDesktopPerson
(this already sounds wrong, doesn't it? The naming is simply not about the kind of Person - it's about something else).Each UI could work on different kinds of Persons, e.g.
Teacher
andStudent
. So we getWebPerson
,WebTeacher
,WebStudent
,DesktopPerson
,DesktopTeacher
andDesktopStudent
.Now let's say,
WebPerson
defines the method "drawAddressFields()" to draw a web version of the address fields. But sinceWebTeacher
has to derive fromTeacher
to use the additional data field "salary" (and let's assume single inheritance), it must implement "drawAddressFields()" once again!So maybe the argument of "this will cause much more work" will help to create some motivation :-)
BTW, it will automatically lead to creating some delegate that implements the code of drawAddressField(), which will then evolve to creating a component that does the drawing separately from the data structure.