繁体   English   中英

如何使用抽象工厂设计模式打开子 window 并在 c# 中绘制/绘制形状?

[英]How to open sub window and draw/paint the shapes in c# using abstract factory design pattern?

我正在 c# 中开发一个简单的命令行图形应用程序。 在此处输入图像描述 就像上面一样,在单击调试/运行或在 window 下方键入运行后,程序会逐行检查预定义的语法。

        private void execute()
            {
                Output outputWindow = new Output(); //object of output window 
                compiler = new Compiler(outputWindow); //sending object of output window to compiler
                //get all text and save in lines string array
                string output = "";
                string[] lines = GetActiveEditor().Lines;
                lines = lines.Where(x => !string.IsNullOrEmpty(x)).ToArray();
                if (lines == null || lines.Length == 0)
                {
                    consoleBox.Text += "\n Error: Compiling Failed. Empty File.";
                }
                else
                {
                    foreach (var line in lines)
                    {
                        output = compiler.Compile(line);
                        consoleBox.Text += "\n" + output;
                        if (output.Contains("Error"))
                        {
                        break;
                        }
                    }

                }


            }

            private void ToolBtnDebug_Click(object sender, EventArgs e)
            {
                consoleBox.Clear();
                consoleBox.Text = " \n CPaint Compiler:- Compiling Started... \n";
                execute();
            }

    // In Compiler 

        string[] commands = { "clear", "reset", "rectangle", "circle", "triangle", "position pen", "pen draw" };
        Public string Line { get; set; }
        Public Output outputWindow;

        public Compiler(Output form)
            {
                outputWindow = form;
            }

        //checks syntax
        public bool IsSyntax(string syntax)
            {
                bool result = false;
                if (Array.Exists(commands, element => element == syntax.ToLower().Trim()))
                {
                    result = true;
                }
                return result;
            }

    //Compile class 
    public string Compile(string line)
            {
                string output = "";
                //splitting the line by comma"," and small brackets "()" and assigning into an string a`enter code here`rray
                string[] code = line.Split(',', '(', ')');
                //removing extra spaces 
                code = code.Where(x => !string.IsNullOrEmpty(x)).ToArray();
    bool checkSyntax = IsSyntax(code[0]);
                if (checkSyntax == true)
                {
                  if (code[0].Trim().ToLower().Equals("circle"))
                    {
                        try
                        {
                                int parameter1 = Int32.Parse(code[1]);
                                int parameter2 = Int32.Parse(code[2]);
                                //string shapeType = "circle";

                                ShapeFactory shapeFactory = new ShapeFactory();
                                Circle circle = shapeFactory.GetShape("circle").Shape as Circle;
                                circle.Draw(12, 12);
                                output = "command executed successfully: parameter is" + parameter1;
                                //      output = "is numeric ";
                            }

                        }
                        catch (Exception ex)
                        {

                            Console.WriteLine("Exception Message: " + ex.Message);
                            output = "\n Parameter Error : Invalid/Insufficient Parameter. \n";
                        }

                    }

在形状工厂方法中:

class ShapeFactory:AbstractFactory
{
    public override FactoryShape GetShape(string shapeType)
    {
        FactoryShape factoryShape = null;
        if (shapeType.Equals("circle"))
        {
            factoryShape = new FactoryShape(new Circle());
        }

        return factoryShape;
    }
}
        //Circle Method Code: 
            namespace CPaint.Class
            {
            class Circle
            {
                Graphics graphics;
                public void Draw(float initX, float initY)
                {
                    Output outputWindow=new Output();
                    Graphics graphics=outputWindow.outputArea.CreateGraphics();
                    outputWindow.outputArea.Image=Color.Red;
                    Pen pen = new Pen(Color.Black, 4);
                    SolidBrush brush = new SolidBrush(Color.Black);
                    graphics.FillEllipse(brush, 12, 12, 12, 12);
                    graphics.DrawEllipse(pen, 12, 12, 12, 12);
                    Console.WriteLine("ok drawing circle for you" + initX + "   " + initY);
output.show();
                }
            }
            }

此代码打开两个读取空的 output window,而是应该在同一个 output Z05B8C74CBD96FBFFF2DEZ4C1 中绘制两个圆圈。 请帮忙,我三天以来一直卡在这里。 提前致谢。

首先,我们需要改进您的设计。

  1. 工厂模式只有在您编写抽象代码时才有意义,这意味着工厂应该创建具体类型,但您不应该知道具体类型而只知道抽象类型。 在您的设计中并非如此。 您说您使用的是抽象工厂模式,但是您将创建的 object 转换为 Circle,即“从编码到实现”。

  2. Compiler 将行编译为 Shapes 并执行它们。 编译器只应将文本(代码)转换为可执行的 object,而不应执行它们。 不幸的是,使用您当前的设计,无法将创建的形状传递到 output 表单中并绘制它们。

  3. 您需要将所有已编译的形状传递到您的 output 表单中,并且应该在运行时重新绘制控件(表单)表面的地方绘制 OnPaint 覆盖

抽象(形状):

public abstract class Shape
{
    public abstract void Draw(Graphics surface);
}

具体类型:

public class Circle : Shape
{
    public float Radius { get; set; }

    public override void Draw(System.Drawing.Graphics surface)
    {
        surface.DrawEllipse(Pens.Black, 0, 0, Radius, Radius);
    }
}

public class Rectangle : Shape
{
    public float Width { get; set; }
    public float Height { get; set; }

    public override void Draw(System.Drawing.Graphics surface)
    {
        surface.DrawRectangle(Pens.Black, 0, 0, Width, Height);
    }
}

这是我实现中的 ShapeFactory

public class ShapeFactory
{
    public static Shape CreateShape(string shapeName, params string[] parameters)
    {
        switch (shapeName)
        {
            case "circle":
                return new Circle() { Radius = Convert.ToSingle(parameters[0]) };
            case "rectangle":
                return new Rectangle { Width = Convert.ToSingle(parameters[0]), Height = Convert.ToSingle(parameters[1]) };
            default:
                throw new NotSupportedException("shapeName");
        }
    }
}

编译器:

public Shape Compile(string line)
{
    string[] code = line.Split(new char[] { ',', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
    if (IsSyntax(code[0]))
    {
        try
        {
            return ShapeFactory.CreateShape(code[0], code.Skip(1).ToArray());
        }
        catch (Exception shapeCreationException)
        {
            // Exception handling here.
            // . . .
        }
    }
    else
    {
        // Syntax Error handling here
        // . . .
    }
    return null;
}

最后是 output 形式:

public partial class Output : Form
{
    public List<Shape> Shapes { get; set; }

    public Output()
    {
        Shapes = new List<Shape>();
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        foreach (Shape shapeToDraw in Shapes)
        {
            shapeToDraw.Draw(e.Graphics);
        }
    }
}

和 execute() 方法:

private void execute()
{
    Output outputWindow = new Output();
    Compiler compiler = new Compiler();

    string[] lines = { "circle(24)", "rectangle(80,56)" };

    foreach (var line in lines)
    {
        try
        {
            Shape compiledShape = compiler.Compile(line);
            outputWindow.Shapes.Add(compiledShape);
        }
        catch
        {
            // Exception handling here
            // . . .
        }
    }

    outputWindow.Show();
    outputWindow.Invalidate();
}

这是经过测试和工作的。

如果您不了解某些内容或无法完成这项工作,请发表评论,但不幸的是,由于其设计缺陷,您的案例没有简单的修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM