There is a Name class with properties that represent different components that make up a person's name. A Name object requires a FirstName
and Surname
. All other fields are optional.
class Name
{
public string FirstName { get; set; } = String.Empty;
public string Surname { get; set; } = String.Empty;
public string Rank { get; set; } = String.Empty;
public string Suffix { get; set; } = String.Empty;
public string NickName { get; set; } = String.Empty;
public string MiddleName { get; set; } = String.Empty;
public Name(string firstName, string surname)
{
this.FirstName = firstName;
this.Surname = surname;
}
}
Also, there is a NamesBuilder class that has a List<Name>
collection. It has a GetListAsString
method which iterates over the collection and builds a single string with the list of names:
class NamesBuilder
{
List<Name> Names;
public NamesBuilder()
{
Names = new List<Name>();
}
public NamesBuilder AddName(string firstName, string surname)
{
Names.Add(new Name(firstName, surname));
return this;
}
public string GetListAsString()
{
StringBuilder sb = new StringBuilder();
foreach (Name name in Names)
{
//add Title if exists
if (name.Rank.Length > 0)
{
sb.Append(name.Rank);
sb.Append(" ");
}
//add Firstname
sb.Append(name.FirstName);
sb.Append(" ");
//add MiddleName if exists
if (name.MiddleName.Length > 0)
{
sb.Append(name.MiddleName);
sb.Append(" ");
}
//add NickName if exists
if (name.NickName.Length > 0)
{
sb.Append((char)34);
sb.Append(name.NickName);
sb.Append((char)34);
sb.Append(" ");
}
//add Surname
sb.Append(name.Surname);
//add Suffix if exists
if (name.Suffix.Length > 0)
{
sb.Append(" ");
sb.Append(name.Suffix);
}
//add new line
sb.AppendLine();
}
return sb.ToString();
}
}
This is called using method chaining:
static void Main(string[] args)
{
NamesBuilder nb = new NamesBuilder()
.AddName("James", "Kirk")
.AddName("Montgomery", "Scott")
.AddName("Nyota", "Uhura")
.AddName("Leonard", "McCoy")
.AddName("Christine", "Chapel");
Console.WriteLine(nb.GetListAsString());
}
And this outputs:
James Kirk
Montgomery Scott
Nyota Uhura
Leonard McCoy
Christine Chapel
So the missing functionality is the ability to add optional Rank, Suffix, NickName and MiddleName details to each name. My initial thought was to change the AddName
method to multiple optional parameters:
public NamesBuilder AddName(string firstName, string surname, string rank = "", string nickName = "", string middleName = "", string suffix = "")
However, this seems very verbose and inelegant especially if only the suffix needs to be added and all previous optional parameters are not applicable to that particular name.
My approach is to create new methods in the NamesBuilder
class that would append those details to the last item added to the collection.
Here is the amended code of the caller illustrating this
static void Main(string[] args)
{
NamesBuilder nb = new NamesBuilder()
.AddName("James", "Kirk").SetRank("Capt").SetMiddleName("Tiberius")
.AddName("Montgomery", "Scott").SetNickName("Scotty").SetRank("Lt Cdr")
.AddName("Nyota", "Uhura").SetRank("Lt")
.AddName("Leonard", "McCoy").SetSuffix("MD").SetNickName("Bones").SetRank("Lt Cdr")
.AddName("Christine", "Chapel");
Console.WriteLine(nb.GetListAsString());
}
And here is the updated NamesBuilder
class:
class NamesBuilder
{
List<Name> Names;
public NamesBuilder()
{
Names = new List<Name>();
}
public NamesBuilder AddName(string firstName, string surname)
{
Names.Add(new Name(firstName, surname));
return this;
}
public NamesBuilder SetRank(string rank)
{
Names[Names.Count - 1].Rank = rank;
return this;
}
public NamesBuilder SetSuffix(string suffix)
{
Names[Names.Count - 1].Suffix = suffix;
return this;
}
public NamesBuilder SetMiddleName(string middleName)
{
Names[Names.Count - 1].MiddleName = middleName;
return this;
}
public NamesBuilder SetNickName(string nickName)
{
Names[Names.Count - 1].NickName = nickName;
return this;
}
public string GetListAsString()
{
StringBuilder sb = new StringBuilder();
foreach (Name name in Names)
{
//add Title if exists
if (name.Rank.Length > 0)
{
sb.Append(name.Rank);
sb.Append(" ");
}
//add Firstname
sb.Append(name.FirstName);
sb.Append(" ");
//add MiddleName if exists
if (name.MiddleName.Length > 0)
{
sb.Append(name.MiddleName);
sb.Append(" ");
}
//add NickName if exists
if (name.NickName.Length > 0)
{
sb.Append((char)34);
sb.Append(name.NickName);
sb.Append((char)34);
sb.Append(" ");
}
//add Surname
sb.Append(name.Surname);
//add Suffix if exists
if (name.Suffix.Length > 0)
{
sb.Append(" ");
sb.Append(name.Suffix);
}
//add new line
sb.AppendLine();
}
return sb.ToString();
}
}
The output is now:
Capt James Tiberius Kirk
Lt Cdr Montgomery "Scotty" Scott
Lt Nyota Uhura
Lt Cdr Leonard "Bones" McCoy MD
Christine Chapel
I have never before used methods like this to alter the data of the most recent item added to a collection. It works and I think it looks much better than multiple optional parameters but I'd appreciate feedback.