Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重构;如何使一个阶级对另一个阶级一无所知? 便条_C#_Refactoring - Fatal编程技术网

C# 重构;如何使一个阶级对另一个阶级一无所知? 便条

C# 重构;如何使一个阶级对另一个阶级一无所知? 便条,c#,refactoring,C#,Refactoring,这个问题不依赖于基于3D的代码,也不依赖于逻辑;它只关注于从一个对象到另一个对象的依赖关系,我试图尽可能全面地描述这个问题。虽然有一些3D背景可能有助于理解代码在做什么,但不需要将A类和B类分开。我相信这项任务将通过一些逻辑的、横向的思考来解决 概述 我正在重构一些旧代码(写在90年代初),有一些类依赖于其他类。这个问题将集中在依赖于另一个类的单个类上(本例中没有其他依赖项)。该项目是一个DirectX项目,它只是为了工作目的而将一些对象渲染到屏幕上。不幸的是,我真的不能给出一个完整的描述;但

这个问题不依赖于基于3D的代码,也不依赖于逻辑;它只关注于从一个对象到另一个对象的依赖关系,我试图尽可能全面地描述这个问题。虽然有一些3D背景可能有助于理解代码在做什么,但不需要将A类和B类分开。我相信这项任务将通过一些逻辑的、横向的思考来解决


概述 我正在重构一些旧代码(写在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
    对象的依赖关系

这类似于您的“创建一个中间人类来处理所有这些”解决方案。然而,中间人除了充当单向快递员外,什么也不做