组合中域和 ui 层的分离
我想知道是否有一种模式如何将类的域逻辑与域层中对象的 ui 职责分开。
示例:
// Domain classes
interface MachinePart
{
CalculateX(in, out)
// Where do we put these:
// Draw(Screen) ??
// ShowProperties(View) ??
// ...
}
class Assembly : MachinePart
{
CalculateX(in, out)
subParts
}
class Pipe : MachinePart
{
CalculateX(in, out)
length, diamater...
}
有一个应用程序计算由许多机器零件组装而成的机器的值 X。该程序集是从文件表示形式加载的,并被设计为复合体。每个具体零件类都存储一些数据来实现 CalculateX(in,out) 方法来模拟整个装配体的行为。该应用程序运行良好,但没有 GUI。为了提高可用性,应该在现有实现的基础上开发 GUI(允许更改现有代码)。 GUI 应显示装配体的示意性图形表示,并提供特定于零件的对话框来编辑多个参数。
为了实现这些目标,应用程序需要为每个机器部件提供新功能,以在屏幕上绘制示意图、显示属性对话框以及与机器模拟领域无关的其他内容。我可以想到一些不同的解决方案来为每个部分实现 Draw(Screen)
功能,但我对它们中的每一个都不满意。
首先,我可以向 MachinePart 接口添加一个 Draw(Screen)
方法,但这会将域代码与 ui 代码混合在一起,我必须向每个机器部件类添加很多功能,这使得我的域模型难以阅读和理解。
另一个“简单”的解决方案是使所有部分都可访问并在访问者中实现 ui 代码,但访问者不属于我最喜欢的模式。
我可以从每个机器部件类派生 UI 变体,以在其中添加 UI 实现,但我必须检查每个部件类是否适合继承,并且必须小心对基类的更改。
我目前最喜欢的设计是创建一个并行的复合层次结构,其中每个组件存储数据来定义机器零件,实现 UI 方法和创建相应域类实例的工厂方法,以便我可以“转换”UI 程序集到域程序集。但是,从创建的域层次结构返回到 UI 层次结构以在绘图中显示计算结果时存在问题(想象一下,某些部件在计算过程中存储了一些值,我想在模拟后在原理图表示中显示)。
也许这些问题有一些经过验证的模式?
i'm wondering if there is a pattern how to separate the domain logic of a class from the ui responsibilities of the objects in the domain layer.
Example:
// Domain classes
interface MachinePart
{
CalculateX(in, out)
// Where do we put these:
// Draw(Screen) ??
// ShowProperties(View) ??
// ...
}
class Assembly : MachinePart
{
CalculateX(in, out)
subParts
}
class Pipe : MachinePart
{
CalculateX(in, out)
length, diamater...
}
There is an application that calculates the value X for machines assembled from many machine parts. The assembly is loaded from a file representation and is designed as a composite. Each concrete part class stores some data to implement the CalculateX(in,out)
method to simulate behaviour of the whole assembly. The application runs well but without GUI. To increase the usability a GUi should be developed on top of the existing implementation (changes to the existing code are allowed). The GUI should show a schematic graphical representation of the assembly and provide part specific dialogs to edit several parameters.
To achieve these goals the application needs new functionality for each machine part to draw a schematic representation on the screen, show a property dialog and other things not related to the domain of machine simulation. I can think of some different solutions to implement a Draw(Screen)
functionality for each part but i am not happy with each of them.
First i could add a Draw(Screen)
method to the MachinePart interface but this would mix-up domain code with ui code and i had to add a lot of functionality to each machine part class what makes my domain model hard to read and hard to understand.
Another "simple" solution is to make all parts visitable and implement ui code in visitors but Visitor does not belong to my favorite patterns.
I could derive UI variants from each machine part class to add the UI implementation there but i had to check if each part class is suited for inheritance and had to be careful on changes to the base classes.
My currently favorite design is to create a parallel composite hierarchy where each component stores data to define a machine part, has implementation for UI methods and a factory method which creates instances of the corresponding domain classes, so that i can "convert" a UI assembly to a domain assembly. But there are problems to go back from the created domain hierarchy to the UI hierarchy for showing calculation results in the drawing for example (imagine some parts store some values during the calculation i want to show in the schematic representation after the simluation).
Maybe there are some proven patterns for such problems?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
同意@Marjin,并概括他的答案。您需要的是 模型-视图-控制器其中MVP和MVVM是其中的变体。从您的评论中我认为您明白这一点,但需要了解如何实现该模式。不知道你的语言和目标架构很难给出绝对的细节。尽管如此,我还是从 Observer 模式开始(链接有示例代码)。
您要处理的问题是如何提供从域到 UI 的可观察访问,而不用特定于 UI 的代码妨碍域。观察者提供了一种方法来做到这一点。它确实需要域更改,特别是为了启用观察员注册和更改通知。然而,其中没有任何特定于 GUI 的内容,因此它保持了良好的封装。
嗯。
PS:如果您的应用程序是典型的瘦客户端 Web 应用程序,您需要修改该方法。请注意:许多 Web 应用程序框架都被宣传为“MVC”,但其实现在架构上与观察者模式有很大不同。
Agree with @Marjin, and to generalise his answer. What you need is Model-View-Controller of which MVP and MVVM are variants. From your comments I think you understand that, but need to understand how to implement the pattern. Without knowing your language & target architecture it's hard to give absolute specifics. Notwithstanding, I'd start with the Observer pattern (link has sample code).
The problem you're dealing with is how to provide observable access from the domain to the UI - without encumbering the domain with UI-specific code. Observer provides a means to do that. It does require domain changes, in particular to enable registration of observers and notification of changes. However there's nothing GUI-specific in that so it stays well encapsulated.
hth.
PS: If your app is a typical thin-client web app you'll need to modify the approach. And beware: lots of web app frameworks are advertised as "MVC", but the implementation is architecturally quite different to the Observer pattern.
您可以查看 model-view-presenter (mvp) 和 model-view-viewmodel (mvvm) 模式。
Fowler 的演示模型 包括两个示例应用程序;您可能也会感兴趣。
我认为研究这些模式将为您提供一些关于如何继续的想法。 Mvvm 看起来很像您当前的解决方案;所以如果我是你我就会从这里开始。
You can take a look at the model-view-presenter (mvp) and model-view-viewmodel (mvvm) patterns.
Fowler's presentation model includes two sample applications; it also might be of interest to you.
I think that investigating these patterns will give you some ideas on how to continue. Mvvm looks a lot like your current solution; so i'd start there if I were you.
也许 View Helper 可以提供帮助。它不是 C++,而是 Java EE 模式,但在您的情况下,它肯定会将您的域对象与其表示细节分开......
Maybe a View Helper can help. It's not a C++, but a Java EE pattern, but in your case it will definitely separate your domain objects from their presentation details...