gpt4 book ai didi

c# - 如何在 C# 中处理组合类

转载 作者:太空狗 更新时间:2023-10-29 22:21:23 25 4
gpt4 key购买 nike

我在问一个关于设计模式的问题。我有一个 IDrawing 接口(interface),以及实现此接口(interface)的两个名为 TextDrawingShapeDrawing 的类。我还有一个 View 类,它知道如何绘制这些类。但是,我有更复杂的绘图类,它们也实现了 IDrawing 接口(interface),但由其他几个 IDrawing 类组成。

我不确定如何在我的 View 类中绘制这些复杂的类。我不想教 View 类如何绘制每个新的 IDrawing 类,因为这不是一个好的设计。我还有哪些其他选择?我的设计是否不正确,如果是这样,我如何告诉 ViewDraw 方法了解复杂类的原始部分并绘制它们?这是我的代码:

   public interface IDrawing
{
}

public class TextDrawing : IDrawing
{
}

public class ShapeDrawing : IDrawing
{
}

public class SignDrawing : IDrawing
{
public TextDrawing Text { get; set; }
public ShapeDrawing Border { get; set; }
}

public class MoreComplexDrawing : IDrawing
{
public TextDrawing Text { get; set; }
public ShapeDrawing Border1 { get; set; }
public ShapeDrawing Border2 { get; set; }
}

public class View
{
public void Draw(IDrawing drawing)
{
// The View only knows how to draw TextDrawing and ShapeDrawing.
// These as the primitive building blocks of all drawings.
// How can it draw the more complex ones!
if (drawing is TextDrawing)
{
// draw it
}
else if (drawing is ShapeDrawing)
{
// draw it
}
else
{
// extract the drawings primitive parts (TextDrawing and ShapeDrawing) and draw them!
}
}
}

更新:

我收到了在我的绘图类中实现 Draw() 方法的建议,但如果我这样做,它们将不再通用。例如,我将无法在我有不同绘图策略的其他项目中使用它们。有没有办法让我的设计更加灵活并保持其通用性?

最佳答案

我会向接口(interface)添加一个 Draw() 方法,并在您的每个类中实现它。

这样做的好处是您的 View 不关心实际类型是什么。

public interface IDrawing
{
void Draw();
}

public class TextDrawing : IDrawing
{
public void Draw()
{
// Draw a TextDrawing
}
}

public class ShapeDrawing : IDrawing
{
public void Draw()
{
// Draw a ShapeDrawing
}
}

public class SignDrawing : IDrawing
{
public TextDrawing Text { get; set; }
public ShapeDrawing Border { get; set; }

public void Draw()
{
// Draw a SignDrawing
}
}

public class MoreComplexDrawing : IDrawing
{
public TextDrawing Text { get; set; }
public ShapeDrawing Border1 { get; set; }
public ShapeDrawing Border2 { get; set; }

public void Draw()
{
// Draw a MoreComplexDrawing
}
}

public class View
{
public void Draw(IDrawing drawing)
{
//Draw the drawing
drawing.Draw();
}
}

更新 - 抽象掉对 SkiaSharp 的依赖

您需要为 SkiaSharp 或实际执行绘图的任何外部依赖项创建一个包装器。这应该与您的 IDrawing 接口(interface)和派生类存在于同一个程序集中。

public interface IDrawingContext
{
// Lots of drawing methods that will facilitate the drawing of your `IDrawing`s
void DrawText(...);
void DrawShape(...);
void DrawBorder(...);
}

以及SkiaSharp具体实现

public class SkiaSharpDrawingContext IDrawingContext
{
// Lots of drawing methods that will facilitate the drawing of your IDrawings
public void DrawText(...) { /* Drawing code here */ }
public void DrawShape(...) { /* Drawing code here */ }
public void DrawBorder(...) { /* Drawing code here */ }
}

更新IDrawing界面为

public interface IDrawing
{
void Draw(IDrawingContext drawingContext);
}

也更新您的类(class)以反射(reflect)这一变化。您的类将调用 IDrawingContext 实现上的方法来进行绘图。

在您的应用程序中创建依赖项特定实现并更新您的 View 类以使用新的 SkiaSharpDrawingContext

public class View
{
public void Draw(IDrawing drawing)
{
// This should ideally be injected using an IOC framework
var drawingContext = new SkiaSharpDrawingContext(...);

//Draw the drawing
drawing.Draw(drawingContext);
}
}

关于c# - 如何在 C# 中处理组合类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45843353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com