微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在C#中处理组合类

我要问的是部分与设计模式有关.

可以说我有一个IDrawing界面.
另外两个名为TextDrawing和ShapeDrawing的基本类实现了这个,我有一个知道如何绘制这些类的View类!

但是我有更复杂的绘图类,它们也实现了IDrawing接口,但它们本身由几个IDrawing类组成!

如何在我的View类中绘制这些?显然教会View类来绘制每个新的IDrawing并不是一个好主意!但我还有其他选择吗?也许设计不正确?如何告诉View的Draw方法知道复杂类的原始部分并绘制它们?

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()方法的建议.
View中的Draw方法依赖于要绘制的外部库(在我的例子中,它是SkiaSharp库).如果我在这些类中实现Draw,它们将不再是通用的!例如,我将无法在其他项目中使用它们,因为我有不同的策略来绘制东西.

解决方法

我会在接口中添加一个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接口和派生类存在于同一个程序集中.

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);
}

更新您的课程以反映此更改.您的类将调用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);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐