下面的代码是工作编码挑战的代码。我已经按照他们的要求做好了所有的事情,我已经亲自复习过了,并且相信一切都很好。我只是想看看是否有人看到我所做的事情可能被认为是不好的做法,或者是否有任何明显的改进,以清理代码或提高性能。欢迎任何反馈意见。
以下是公司给我的指示:
using System;
using System.Collections.Generic;
using System.Linq;
namespace CSECodeSampleConsole
{
public class Program
{
public static void Main(string[] args)
{
Menu menu = new Menu();
menu.MainMenu();
}
}
internal class Person
{
public int Id { get; set; }
public string Name { get; set; }
public static int globalId = 1;
public Person(string name)
{
this.Name = name;
this.Id = globalId;
globalId++;
}
}
internal class Menu
{
List<Person> people = new List<Person>();
public void MainMenu() //Display and Navigate Menu.
{
Console.WriteLine("Please make a selection by entering the corresponding number:");
Console.WriteLine("1.View Persons");
Console.WriteLine("2.Add Person");
Console.WriteLine("3. Search For Person");
Console.WriteLine("4.Exit");
var input = Console.ReadLine();
switch (Convert.ToInt32(input))
{
case 1:
DisplayNames();
break;
case 2:
AddPerson();
break;
case 3:
SearchList();
break;
case 4:
Environment.Exit(0);
break;
default:
Console.WriteLine("Invalid Input\n\n");
MainMenu();
break;
}
return;
}
public void DisplayNames() //Display all names and their Id's in list.
{
if(people.Count == 0)
{
Console.WriteLine("No People To Display Yet.\n\n");
MainMenu();
}
else
{
Console.WriteLine("List of Current People:\n");
foreach (Person person in people)
{
Console.WriteLine(person.Id + " - " + person.Name);
}
Console.WriteLine("\n\n");
MainMenu();
}
return;
}
public void AddPerson() //Add a new person to the list.
{
Console.WriteLine("Please Enter The Person's Name: ");
var result = Console.ReadLine();
Person newPerson = new Person(result);
people.Add(newPerson);
Console.WriteLine(newPerson.Name + " added successfully.\n\n");
MainMenu();
return;
}
public void SearchList() //Find and display search results.
{
Console.WriteLine("Please Enter A Name To Search For: ");
var result = Console.ReadLine();
var searchResults = people.Where(n => n.Name.Contains(result, StringComparison.OrdinalIgnoreCase)).ToList();
if (searchResults.Count == 0)
{
Console.WriteLine("No Results Were Found");
}
else
{
Console.WriteLine("The Following Results Were Found: \n");
foreach (Person person in searchResults)
{
Console.WriteLine(person.Id + " - " + person.Name);
}
}
Console.WriteLine("\n\n");
MainMenu();
}
}
public static class MyExtensionMethods
{
public static bool Contains(this string source, string toCheck, StringComparison comp)
{ //Created this to take away the case sensitivity of the Contains method.
return source != null && toCheck != null && source.IndexOf(toCheck, comp) >= 0;
}
}
}发布于 2019-02-15 19:47:11
代码的
this.Id = globalId;
globalId++;可以简化为
this.Id = globalId++;globalId不应公开
switch (Convert.ToInt32(input)) { ... }这不是一种解析输入的健壮方法。如果用户输入一个字母,您的程序就会崩溃!
MainMenu()可以移动到MainMenu()方法的末尾(作为递归调用)。return。Contains-Extension方法,因为名称和搜索输入都不能为null。Environment.NewLine或Console.WriteLine代替"\n“。很好,有一个person类来存储关于此人的信息。
然而,因为面试官希望一个“可以理解的面向对象的设计”,我也会尝试将不同的菜单案例建模为对象。
例如:
public abstract class MenuEntry
{
public MenuEntry(int id, string description)
{
this.Id = id;
this.Description = description;
}
public int Id { get; }
public string Description { get; }
public abstract void Execut();
}这样就可以在一个单独的类中定义每个菜单项及其逻辑,然后去掉switch语句。
此外,使用新的菜单项扩展程序更简单,而不涉及逻辑;)。
单个类条目的示例实现:
internal class Person
{
public int Id { get; }
public string Name { get; }
private static int globalId = 1;
public Person(string name)
{
this.Name = name;
this.Id = globalId++;
}
}
internal abstract class MenuEntry
{
public MenuEntry(int id, string description)
{
this.Id = id;
this.Description = description;
}
public int Id { get; }
public string Description { get; }
public abstract void Execut();
}
internal class DisplayNames : MenuEntry
{
private readonly List<Person> persons;
internal DisplayNames(List<Person> persons) : base(1, "View Persons")
{
this.persons = persons;
}
public override void Execut()
{
if (persons.Count == 0)
{
Console.WriteLine("No People To Display Yet.");
}
else
{
Console.WriteLine("List of Current People:");
persons.ForEach(p => Console.WriteLine(p.Id + " - " + p.Name));
}
}
}
internal class AddPerson : MenuEntry
{
private readonly List<Person> persons;
internal AddPerson(List<Person> persons) : base(2, "Add Person")
{
this.persons = persons;
}
public override void Execut()
{
Console.WriteLine("Please Enter The Person's Name: ");
var result = Console.ReadLine();
Person newPerson = new Person(result);
persons.Add(newPerson);
Console.WriteLine(newPerson.Name + " added successfully.");
}
}
internal class Exit : MenuEntry
{
internal Exit() : base(9, "Exit")
{
}
public override void Execut()
{
Environment.Exit(0);
}
}
internal class Menu
{
private readonly List<Person> persons = new List<Person>();
private readonly List<MenuEntry> entries = new List<MenuEntry>();
public Menu()
{
this.entries.Add(new DisplayNames(this.persons));
this.entries.Add(new AddPerson(this.persons));
// ... other entries
this.entries.Add(new Exit());
}
public void Show()
{
Console.WriteLine("Please make a selection by entering the corresponding number:");
this.entries.ForEach(p => Console.WriteLine($"{p.Id}. {p.Description}"));
var input = Console.ReadLine();
int entryId = -1;
MenuEntry entry = null;
if (int.TryParse(input, out entryId))
{
entry = this.entries.FirstOrDefault(e => e.Id == entryId);
entry?.Execut();
}
if (entry == null)
{
Console.WriteLine("Invalid Input.");
}
Console.WriteLine();
Console.WriteLine();
this.Show();
}
}发布于 2019-02-15 20:08:25
我不是C#程序员,但以下是一些一般性的反馈:
你叫menu.MainMenu(),但没有动词!宾语是名词,方法应该是动词。也许可以给方法命名为DisplayMenu或DispatchUserAction,或者某种表示活动正在发生的东西?
您的MainMenu方法似乎不处理无效输入。如果用户点击返回会发生什么?EOF?“Abcde”
我看到的失败模式只是递归地调用自己。所以,我可以用一系列9's作为输入来耗尽你的程序吗?放入一个while true循环,或者类似的东西。可能循环并调用内部方法,以获得较小的清晰代码。
Person构造函数还更新id计数器。更改它,以便独立地管理id。如果提供的话,可以使用可选参数并强制id计数器高于该值吗?
您有一些尴尬的代码来实现您的搜索。为什么您的比较逻辑在菜单类中,还是在第三方类中?我认为询问一个人的名字是否与字符串匹配是Person类应该处理的事情:
foreach (Person guy in people)
if (guy.isThisYou(target))
etc.我刚刚注意到,您通过递归处理到主菜单的所有返回。别干那事。返回并在主菜单中编写一个循环。
您有很多用于输入和输出的与控制台交互的模式。将它们转化为专用的辅助函数/方法。示例:打印两行换行符以分隔“段落”可以是NewParagraph();写一行然后读取一行可以是GetInput (String prompt)。
如果可能的话,将输入流和输出流分离到变量中,并对这些流变量进行读写。这将使编写一些测试用例成为可能:用字符串流构造菜单,并将输出与输入的期望值进行比较。
https://codereview.stackexchange.com/questions/213535
复制相似问题