C# 重构;如何使一个阶级对另一个阶级一无所知? 便条
这个问题不依赖于基于3D的代码,也不依赖于逻辑;它只关注于从一个对象到另一个对象的依赖关系,我试图尽可能全面地描述这个问题。虽然有一些3D背景可能有助于理解代码在做什么,但不需要将A类和B类分开。我相信这项任务将通过一些逻辑的、横向的思考来解决C# 重构;如何使一个阶级对另一个阶级一无所知? 便条,c#,refactoring,C#,Refactoring,这个问题不依赖于基于3D的代码,也不依赖于逻辑;它只关注于从一个对象到另一个对象的依赖关系,我试图尽可能全面地描述这个问题。虽然有一些3D背景可能有助于理解代码在做什么,但不需要将A类和B类分开。我相信这项任务将通过一些逻辑的、横向的思考来解决 概述 我正在重构一些旧代码(写在90年代初),有一些类依赖于其他类。这个问题将集中在依赖于另一个类的单个类上(本例中没有其他依赖项)。该项目是一个DirectX项目,它只是为了工作目的而将一些对象渲染到屏幕上。不幸的是,我真的不能给出一个完整的描述;但
概述 我正在重构一些旧代码(写在90年代初),有一些类依赖于其他类。这个问题将集中在依赖于另一个类的单个类上(本例中没有其他依赖项)。该项目是一个DirectX项目,它只是为了工作目的而将一些对象渲染到屏幕上。不幸的是,我真的不能给出一个完整的描述;但是,我可以用代码解释问题 有两个类我需要重点关注,其中一个类我目前正在重新编写,以使其具有通用性和可重用性,因为我们现在有第二个渲染需求
- Engine3D(当前正在重新编写)
- Camera3D
Engine3D
依赖于Render
方法中的Camera3D
Engine3D
的当前流
当前的Engine3D
流程主要集中于实现单一目标;呈现项目所需的内容,仅此而已
public void Render() {
// Clear render target.
// Render camera.
// Set constant buffers.
// Render objects.
// Present back buffer.
}
更新代码和渲染代码都混在一起,渲染到屏幕上的每个对象都位于render
方法中。这不利于重用,因为它会强制每次渲染完全相同的场景;因此,我将其分解,创建一个通用的Engine3D
,然后在我的(我们称之为Form1
)代码中使用它
新流程 其思想是通过调用
Engine3D
并传入要渲染的对象,使向屏幕渲染对象成为一项简单的任务。很像以前的XNA框架
。Engine3D
新流程的基本表示形式是:
// I may move this to the constructor; if you believe this is a good idea, please let me know.
public new virtual void Initialize() {
base.Initialize();
OnInitialize(this, new EventArgs());
RenderLoop.Run(Window, () => {
if (!Paused) {
OnUpdate(this, new EventArgs());
Render();
}
});
}
protected override void Render() {
// Clear Render Target. context.ClearRenderTargetView(...);
// Set constant buffers.
OnRender(this, new EventArgs());
// Present back buffer.
}
其中,OnUpdate
将用于更新屏幕上的任何对象,OnRender
将处理新的Draw
调用
问题 问题是,旧流(在渲染循环中)清除了渲染目标,然后渲染了摄影机,然后开始设置常量缓冲区。我已经相当容易地完成了列表中的第一个,列表中的第二个是一个简单的
Draw
调用和新的流(可以在设置缓冲区之后进行);但问题是设置常量缓冲区。以下代码行需要使用Camera3D
对象,我在移动该对象时遇到问题
ConstantBuffers.PerFrame perFrame = new ConstantBuffers.PerFrame();
perFrame.Light.Direction = (camera.TargetPosition - camera.Position);
perFrame.CameraPosition = camera.Position;
perFrame.CameraUp = camera.Up;
context.AddResource(perFrame);
然后将此变量添加到渲染目标的资源列表中,该资源列表必须保留在Engine3D
中,以防止图形代码过于复杂
代码后面还有其他依赖于Camera3D
的World
属性的对象,但一旦我解决了如何将Engine3D
与Camera3D
分离的问题,我相信我可以轻松处理其余的对象
问题 如何将此依赖项与
Engine3D
类分离
我想到的几件事是:
- 创建一个方法,该方法设置在绘制之前必须调用的缓冲区
- 将这些属性设置为静态的
,因为始终只有一个摄像头,而不是更多Camera3D
- 创建专门用于处理此问题的摄影机的方法
- 创建一个中产阶级来处理这一切
- 组合
和Engine3D
类Camera3D
如果对我试图实现的目标有任何疑问,请告诉我,我将尽我所能澄清。您想要进行的重构称为
您提出的解决方案是: 使这些属性在Camera3D上保持静态,因为始终只有一个摄影机,而不是更多
我建议:
- 您可以创建另一个类(将其命名为
),该类包含StudioSetup
中所需的字段(您希望在Engine3D
中实现静态)李>Camera3D
- 用当前值填充该类的对象,并将其传递给
李>Engine3D->Render()
- 现在,对
的依赖关系已替换为对Camera3D
对象的依赖关系StudioSetup
这类似于您的“创建一个中间人类来处理所有这些”解决方案。然而,中间人除了充当单向快递员外,什么也不做