scala - Scala:UI对象/渲染器的设计模式
问题描述
有什么好的设计renderer
和object
.
我做了一些尝试,但我的代码现在真的很难看。
假设我有一个类room
和一个应该处理渲染它的类。
- 谁应该打电话
renderer.render(room)
,甚至应该这样? - 我应该有
world.renderRoom()
吗? - 或者我应该有
room.renderWith(renderer)
?
如何构建简单的单元测试,例如renderer.render(room, userInteraction)
回报应该是多少?
world.renderRoom().interact()....
?
如您所知,我不知道该怎么做哈哈。
我有几年编写软件的经验,但我正在尝试ScalaZ
并试图变得更像functional-programming
;这对我来说是新的。
谢谢
解决方案
您似乎在询问许多不同的事情,这使得除了以非常笼统的方式之外很难回答。
不要向数据对象添加渲染代码,因为这会破坏关注点分离。Shape
带有方法的类的经典 OO 示例draw
非常适合教学,但它将有关形状的数据(例如边数)与特定的绘制方式相结合。相反,创建一个函数render(s: Shape)
,使用 中的数据以Shape
您想要的特定方式(2D、3D 填充、坐标列表等)进行绘制。
使您的render
代码具有功能性,以便它返回渲染的数据,而不是调用渲染库作为副作用。渲染库需要能够正常工作并返回渲染结果,而不是直接绘制到屏幕上。
将渲染库传递给render
函数(作为implicit
参数)而不是使用全局对象。这允许您使用模拟渲染器测试渲染,并且无论如何都是更灵活的设计。render
但是对于不同的输出设备或样式,您可能仍需要不同的功能。
将渲染与渲染组件的组合分开,以便您可以独立测试它们。
以功能性方式构建整个图像,然后进行单个非功能性操作来显示新图像(通过替换当前图像)。
使用用户交互创建带有更新的修改场景,room
然后重新渲染整个场景。
TL;博士
val room = Room(width, length, height)
val room3D = render(room, render3D)
val house = compose(room3d, ..., compose3D)
screen.display(house)
推荐阅读
- mysql - 我应该规范化这些字段吗?
- jhipster - 启用 jhipster 项目缓存
- javascript - Firefox WebExtensions tabs.onUpdated 参数不正确
- android - 下载选项以离线工作 - Android
- ios - Apple Wallet 通过竞争
- servicestack - ServiceStack.OrmLite:写/读慢?
- node.js - 将其他文件夹中的 nodejs 模块包含到项目文件夹中
- c# - 在 C# 中使用多个字段对 ListBox 进行排序
- django - 如何使用 ORDER BY Chinese USERNAME 查询(转换为 gbk?) - Django,psql
- java - 即使在新项目中,几个小时后也无法扩展 RecyclerView.Adapter