Как открыть подокно и нарисовать / нарисовать фигуры в c#, используя абстрактный шаблон фабричного дизайна? - PullRequest
0 голосов
/ 05 апреля 2020

Я работаю над простым графическим приложением командной строки в c#. enter image description here Как и выше, после нажатия кнопки отладки / запуска или ввода прогона в нижнем окне Программа проверяет предопределенный синтаксис построчно.

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

                    }

In Shape Factory Method:

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

Этот код открывает два пустых окна вывода, вместо этого он должен нарисовать два круга в одном окне вывода. Пожалуйста, помогите, я застрял здесь с трех дней. Заранее спасибо.

1 Ответ

1 голос
/ 08 апреля 2020

Прежде всего, нам нужно улучшить ваш дизайн.

  1. Фабричный шаблон имеет смысл, только если вы кодируете абстракцию, а это значит, что фабрика должна создать конкретный тип, но вы не должны знать конкретный тип, а только абстрактный тип. Это не так в вашем дизайне. Вы говорите, что используете абстрактный шаблон фабрики, но приводите созданный объект к Circle, который является «кодированием для реализации».

  2. Компилятор как компилирует строки в Shapes, так и выполняет их. Компилятор должен только преобразовывать текст (код) в исполняемый объект и не должен их выполнять. К сожалению, с вашим текущим дизайном невозможно передать созданные формы в выходную форму и нарисовать их.

  3. Вам нужно передать все скомпилированные формы в выходную форму, и должен рисовать в переопределении 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;
}

И, наконец, форма вывода:

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

Это проверено и работает.

Пожалуйста, прокомментируйте, если вы чего-то не понимаете или не можете получить это работать, но, к сожалению, ваш случай не так просто исправить из-за его конструкции fl aws.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...