I had an exercise as below for an interview. I used two design patterns: factory and decorator. I put my code at the end of it.
How could I improve the solution?
Basic OOD & Solution Design Requirements
Develop a simple Visual Studio CONSOLE Application which simulates a vector-based drawing package.
Your application should support the following 5 drawing primitives (we'll call them widgets):
1) rectangle 2) square 3) ellipse 4) circle 5) textbox
The application should allow a user to Add a new widget to the drawing, stating the location and size/shape of the widget.
The location can be a standard x/y coordinate on an imaginary page. The size/shape depends on the widget, as follows:
- rectangle – width and height
- square – width
- ellipse –horizontal and vertical diameter
- circle – diameter
- textbox – bounding rectangle (i.e., the rectangle which surrounds the textbox; the text will be centred within this rectangle).
NOTE: - there is no need to worry about rotation. - integer units are fine for all dimensions. - for the textbox you only need to configure the text to display (which will be rendered horizontally within the bounding rectangle). Don’t worry about font face /size / alignment, etc. - as per our coding standards, please use a separate .cs file for each class.
Your console application should be able to 'print out' the current drawing by printing the key details of each widget (type, location, size/shape) to the console.
You don't need to actually render the widgets in any manner - we're just simulating a drawing package at this stage.
Your application can use the Console Application Main() method to test the drawing simulator by adding a hard-coded set of widgets to the drawing.
PLEASE ADD ONE OF EACH WIDGET TO YOUR DRAWING
** Important Note: You DO NOT need to concern yourself with handling any input from the user. Our widgets will be hard-coded within the Main() method.
Time allowed: 2 hours.
My solution follows:
public interface IDraw
{
void Print();
}
class Shape
{
private int X { get; set; }
private int Y { get; set; }
public Shape(int x, int y)
{
this.X = x;
this.Y = y;
}
public string GetLocation()
{
return "(" + this.X + "," + this.Y + ")";
}
}
class Square : Shape, IDraw
{
public Square(int x, int y) : base(x, y)
{
}
public int size { get; set; }
public void Print()
{
Console.WriteLine("{0} {1} size={2}", typeof(Square).Name, base.GetLocation(), this.size);
}
}
class Rectangle : Shape, IDraw
{
public int Width { get; set; }
public int Height { get; set; }
public Rectangle(int x, int y) : base(x, y)
{
}
class Textbox : Rectangle, IDraw
{
public Textbox(int x, int y)
: base(x, y)
{ }
public string Text { get; set; }
public new void Print()
{
Console.WriteLine("{0} {1} Width={2} Height={3} Text={4}", typeof(Textbox).Name, base.GetLocation(), this.Width, this.Height, "\"" + this.Text + "\"");
}
}
public void Print()
{
Console.WriteLine("{0} {1} Width={2} Height={3} ", typeof(Rectangle).Name, base.GetLocation(), this.Width, this.Height);
}
}
class Ellipse : Shape, IDraw
{
public Ellipse(int x, int y) : base(x, y)
{
}
public int HorizontalDiameter { get; set; }
public int VerticalDiameter { get; set; }
public void Print()
{
Console.WriteLine("{0} {1} diameterH={2} diameterY={3}", typeof(Ellipse).Name, base.GetLocation(), this.HorizontalDiameter, this.VerticalDiameter);
}
}
class Circle : Shape, IDraw
{
public Circle(int x, int y) : base(x, y)
{
}
public int size { get; set; }
public void Print()
{
Console.WriteLine("{0} {1} size={2}", typeof(Circle).Name, base.GetLocation(), this.size);
}
}
class Program
{
static void Main(string[] args)
{
//Hard-coded set of widgets
var widgets = new List<IDraw>()
{
new Rectangle(10, 10) { Width = 30, Height = 40 },
new Square(15, 30) { size = 35 },
new Ellipse(100, 150) { HorizontalDiameter = 300, VerticalDiameter = 200 },
new Circle(1, 1) { size = 300 },
new Textbox(5, 5) { Width = 200, Height = 100, Text = "Sample text!" }
};
foreach (var widget in widgets)
{
try
{
widget.Print();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.ReadKey();
}
}