Question & Problem Description
Hello Everyone, this is my first Stack Overflow Question, I tried to be as clear as possible.
I'm trying to develop a kind of Library that helps me when I need to build a Command Line Application.
Since I started its development I have had problems thinking with the use of a good architecture. At the moment, my library has a single functionality and is printing a kind of "responsive" menu in the command line screen, it is more simple that it sounds.
To solve this scenario while trying to follow the SOLID principles I created a class called UIMenu
that has the responsibility of giving access the object properties and methods. Then I created another class named UIMenuPrinter
that has the responsibility of printing a UIMenu
with a specified format.
All is working correctly, but even with this division of responsibility I found a little bit tedious to create a UIMenu
object and then creating a UIMenuPrinter
object to pass as a parameter the previous UIMenu object. So I would like to know what do you think, is this solution a good design or maybe I should improve in something. I was also thinking about implementing the UIMenuPrinter
as a Inner Class, so I don't need to instantiate another object.
I was looking for ideas through Google OC, but all that I found was in general talking about SOLID Principles and good practices.
If you have suggestions I'm all ears!
Solution Code
UIMenu Class
using System.Collections.Generic;
namespace CLILibrary
{
public class UIMenu : UIControl
{
public string Title { get; set; }
public List<string> MenuRows { get; }
public UIMenu() => MenuRows = new List<string>();
public void AppendLine(string line)
{
MenuRows.Add(line);
}
}
}
UIMenuPrinter Class
using System;
using System.Collections.Generic;
using System.Text;
using CLITools;
namespace CLILibrary.UIComponentPrinters
{
public class UIMenuPrinter : UIComponentPrinter
{
public UIMenu UiMenu { get; set; }
public char FrameDecorationChar { get; set; } = '=';
public char SeparationChar { get; set; } = ' ';
public char RowDecorationChar { get; set; } = '|';
public UIMenuPrinter (UIMenu uiMenu)
{
UiMenu = uiMenu;
}
public override void Print()
{
var values = new Stack<string>();
_StackPropertiesLoader(ref values);
var stringMeter = new StringMeter(values);
var largestStringSize = stringMeter.MeasureLargestString();
var largestString = (largestStringSize >= 40) ? largestStringSize : 40;
StringBuilder formatBuilder = new StringBuilder();
var frameDecorationLine = StringRepeater.Repeat(FrameDecorationChar.ToString(), (int) largestString);
var spacesLine = StringRepeater.Repeat(SeparationChar.ToString(), (int) largestString);
formatBuilder.Append(SeparationChar).Append(frameDecorationLine).Append(SeparationChar);
formatBuilder.AppendLine();
formatBuilder.Append(RowDecorationChar).Append(spacesLine).Append(RowDecorationChar).AppendLine();
formatBuilder.Append(RowDecorationChar).Append(_FillRow(UiMenu.Title, (int) largestString)).Append(RowDecorationChar).AppendLine();
formatBuilder.Append(RowDecorationChar).Append(spacesLine).Append(RowDecorationChar).AppendLine();
formatBuilder.Append(SeparationChar).Append(frameDecorationLine).Append(SeparationChar).AppendLine();
UiMenu.MenuRows.ForEach(Row =>
{
formatBuilder.Append(RowDecorationChar).Append(_FillRow(Row, (int) largestString)).Append(RowDecorationChar).AppendLine();
});
formatBuilder.Append(SeparationChar).Append(frameDecorationLine).Append(SeparationChar).AppendLine();
Console.WriteLine(formatBuilder.ToString());
}
private string _FillRow(string row, int limitLength)
{
return $"{row}{StringRepeater.Repeat(SeparationChar.ToString(), limitLength - row.Length)}";
}
private void _StackPropertiesLoader(ref Stack<string> propertiesStack)
{
foreach (string Row in UiMenu.MenuRows)
{
propertiesStack.Push(Row);
}
propertiesStack.Push(UiMenu.Title);
}
}
}
SandBox Console Application for Basic Testing Code
using System;
using CLILibrary;
using CLILibrary.UIComponentPrinters;
using CLITools;
namespace SandBox
{
internal class Program
{
public static void Main(string[] args)
{
var mainMenu = new UIMenu
{
Title = "Do you like to drink coffee?"
};
mainMenu.AppendLine("[1] Yes");
mainMenu.AppendLine("[2] No");
var uiMenuPrinter = new UIMenuPrinter(mainMenu);
uiMenuPrinter.FrameDecorationChar = '*';
uiMenuPrinter.Print();
Console.ReadLine();
}
}
}
Extra Details
-
Also I have one class that is an Abstract Class named
UIControl
that is the Parent of all the specific UI Components likeUIMenu
is. -
Also with the
UIPrinter
object I have a Parent of all the Component Printers, its name isUIComponentPrinter
.
Aucun commentaire:
Enregistrer un commentaire