简体   繁体   English

C#中的派生类的可视化

[英]Visualisation of derived classes in C#

I have a base class (representing a real world container filled with small spheres) and some derived classes. 我有一个基类(代表一个充满小球的现实世界的容器)和一些派生类。 This works just fine. 这样很好。
My problem is how to do their visualisation. 我的问题是如何进行可视化。 I have a UserControl visualising the base class. 我有一个可视化基类的UserControl。 Is the best solution to have a derived UserControl for each of the derived classes? 是否为每个派生类都具有派生UserControl的最佳解决方案? Or is it better to have just one working for all of them? 还是只让一个人为所有工作更好?
Edit: 编辑:
Apparently I was not specific enough. 显然我不够具体。 There is always the same basic appearance: rectangle with a lot of circles inside. 基本外观总是相同的:内部有很多圆的矩形。 The difference between the classes is how the container is filled. 这些类之间的区别是容器的填充方式。 One type puts a seed in the middle and creates other spheres in a tree like structure - in this case the connecting lines between parents and their children should be drawn. 一种类型将种子放在中间,并在树状结构中创建其他球体-在这种情况下,应绘制父母与子女之间的连接线。
Generally there should be consistent look of the classes' visualisations with a few specialities for each derived type. 通常,应该对类的可视化效果保持一致,并为每种派生类型提供一些特色。

This really depends a great deal on how similar the displays will be. 这实际上很大程度上取决于显示器的相似程度。 If the displays of the derived classes are very similar to the base class then you only need the one UserControl to do the visiualization. 如果派生类的显示与基类非常相似,则只需要一个UserControl即可进行可视化。 OTOH, if each derived class needs to display unique things then you will be better off having a separate UserControl to visualize each derived class. OTOH,如果每个派生类都需要显示唯一的内容,那么最好有一个单独的UserControl来可视化每个派生类。 I really can't be any more specific without more specific info on your classes. 没有您班上的更多具体信息,我真的不能再具体了。

EDIT: From your additional info I would say that you should have a base display class that draws the commom rectangular container then have derived UserControls that handle drawing the contents of each specific type. 编辑:从您的附加信息,我想您应该有一个基本的显示类,它绘制commom矩形容器,然后派生了UserControls,该UserControls可以处理每种特定类型的内容。

I suspect only you can answer that question definitively. 我怀疑只有您才能明确回答这个问题。 A UI for a given subclass is likely what you want, but if the subclasses differ only slighltly, you could find it easier to add some conditional logic in fewer user controls. 给定子类的UI可能是您想要的,但是如果子类仅稍有不同,您会发现在较少的用户控件中添加一些条件逻辑会更容易。 I don't think there is One Right Answer to this one. 我认为对此没有一个正确答案。

It hard to say from just the vague description. 仅凭模糊的描述很难说。 We'd really need to know, at the least, what are the differences among the derived classes. 我们真的至少需要知道派生类之间的区别是什么。

Generally, with limited knowledge, I'd go with one derived UserControl per derived class 通常,由于知识有限,我会为每个派生类使用一个派生的UserControl

If the derived classes visualization does not differ from each other, then, by all means, use one UserControl. 如果派生类的可视化效果互不相同,则请务必使用一个UserControl。 The main point here is DRY. 这里的重点是干。

One approach to the problem would be decomposing it following the MVVC perspective: 解决该问题的一种方法是按照MVVC的观点将其分解:

You will need one UserControl as a View. 您将需要一个UserControl作为一个视图。

One base Painter, which handles the painting of your "box with circles in it" as a ViewModel. 一个基础Painter,它作为ViewModel处理“框内有圆圈的框”的绘制。 Derived Painters implement different positioning logic of objects and their interconnections. 派生的画家实现了对象及其互连的不同定位逻辑。

If the look of your objects can vary then they themselves should be given to the painter as ViewModel possibly through the Adapter pattern. 如果对象的外观可以变化,则应通过Adapter模式将它们本身作为ViewModel提供给画家。

And finally your circles, rectangles and items associated with them are the Model. 最后,您的圆,矩形和与之关联的项目就是模型。

Generally speaking: 一般来说:

View (UserControl) -> ViewModel (Painter + derived Painters + object ViewModels) -> Model (circle, rectangle, etc) 视图(UserControl)-> ViewModel(画家+派生的Painters +对象ViewModels)->模型(圆形,矩形等)

I don't fully understand your problem domain but i think you need to break this up some more. 我不完全了解您的问题领域,但我认为您需要进一步解决。 decompose your model into parts and write views for each part then you can just wire them back up. 将模型分解成多个部分,并为每个部分编写视图,然后只需将它们连接起来即可。

I would write a View for your Spheres, a view for lines between your spheres and a view for the rectangle holding everything then each of your models will be responsible for arranging these and creating the corresponding SphereModels and LineModels (and whatever else you need)then your main view just needs to be responsible for laying these out in the box. 我将为您的球体编写一个View,为球体之间的直线编写一个View,并为包含所有内容的矩形编写一个View,然后每个模型将负责排列这些模型并创建相应的SphereModels和LineModels(以及您需要的其他任何模型),然后您的主要观点只需要负责将它们放在框中。

Remember always prefer composition to inheritence! 请记住,始终喜欢使用组合而不是继承! Focus on breaking up your problem into smaller pieces. 专注于将您的问题分解为较小的部分。

good luck 祝好运

I think I would go with a base Visualizer class that had some protected methods for drawing the circles and lines, and maybe some property for the drawing surface (Canvas?) so each implementation can compute measurement-based positions, etc. 我想我可以使用基本的Visualizer类,该类具有一些用于绘制圆和线的受保护方法,并且可能具有某些绘制表面的属性(画布?),以便每个实现都可以计算基于测量的位置,等等。

The base class implements all the necessary interface methods/props to make it a visualizer. 基类实现了所有必要的接口方法/属性,使其成为可视化工具。

Use the strategy pattern in the method called by IDE when your visualizer is supposed to draw itself... that method implementation could clear the canvas, set up brushes, and other things that are to be common to every implementation - then call an abstract method of the base class that actually places the circles/boxes/lines/etc on the canvas. 当您的可视化工具应该绘制自己时,请在IDE调用的方法中使用策略模式...该方法实现可以清除画布,设置画笔以及每个实现所共有的其他内容-然后调用抽象方法基类的实际位置,它们实际上将圆/框/线/等放置在画布上。

This way, each specific implementation then only has to worry about the logic to correctly position stuff according to its set of rules - all the "drawing stuff on the canvas" is kept in the base class. 这样,每个特定的实现只需要担心根据其规则集正确定位内容的逻辑-所有“在画布上绘制内容”都保留在基类中。

HTH 高温超导

EDIT: Corrected typo that may have caused confusion, where I used the word "control" when I meant "visualizer." 编辑:纠正了可能引起混乱的错字,当我指的是“可视化工具”时,我使用了“控制”一词。

This sounds like a situation with multiple solutions. 这听起来像是有多种解决方案的情况。

One way to do it would be to set up the UserControl to call a virtual method in the base class, and then override it in the derived classes. 一种方法是将UserControl设置为在基类中调用虚拟方法,然后在派生类中重写它。 In the derived classes, you could just call the base implementation to set up the frame initially. 在派生类中,您可以只调用基本实现来初始设置框架。

You could also set it up to render in layers (a container layer, sphere layer, line layer, etc.), and have the child class render any unique layers, and determine order. 您还可以将其设置为在图层(容器图层,球面图层,线图层等)中进行渲染,并让子类渲染任何唯一的图层并确定顺序。 This can be expensive, but it could smooth the visuals if most of the image stays the same. 这可能很昂贵,但如果大多数图像保持不变,则可以使视觉效果平滑。

Another is to use delegates as opposed to inheritance, but this tends to get messy. 另一种方法是使用委托而不是继承,但这会变得混乱。 This is generally not a good idea due to performance penalties. 由于性能下降,这通常不是一个好主意。 However, it does have the advantage of runtime flexibility. 但是,它确实具有运行时灵活性的优势。 Depending on the rest of your code, you might be able to switch styles of growth mid-way through with this model. 根据代码的其余部分,您可能可以在此模型的中途切换增长方式。 If you don't see yourself taking advantage of this flexibility, I would recommend you use a different model, though. 如果您没有发现自己在利用这种灵活性,那么我建议您使用其他模型。

No matter what method you use, I would recommend that the base class provide the common drawing routines to ensure consistency. 无论使用哪种方法,我都建议基类提供通用的绘制例程以确保一致性。 The routines in the base class should be used by most child classes, but not necessarily all. 大多数子类都应使用基类中的例程,但不一定要全部使用。 This usually results in more manageable code (unless you end up with a 10000 line file), fewer bugs, and less effort. 通常,这将导致更易于管理的代码(除非最终得到10000行文件),更少的错误和更少的工作量。

That sound for me like the decorator pattern: 对我来说,这听起来像是装饰器模式:

http://en.wikipedia.org/wiki/Decorator_pattern http://en.wikipedia.org/wiki/Decorator_pattern

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM