Проблема
У меня проблема с дизайном, которую я не могу решить с умом.Я уверен, что есть подходящее решение, но я не могу понять, как этого добиться.Мне все еще удавалось работать над своим кодом, но результат ужасен, и я хочу изучать лучшие проекты.
Я приложил все усилия, чтобы обеспечить минимальную реализацию с минимальным минимумом.Поэтому некоторые аспекты могут выглядеть странно.Я надеюсь, что у меня все получится.
Контекст
Итак, во-первых, у меня есть эти простые классы, которые реализуют один и тот же интерфейс:
public interface Human
{
string getName();
}
public class Adult : Human
{
public Adult(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
public class Child : Human
{
public Child(string name, string toy)
{
Name = name;
Toy = toy;
}
public string Name { get; set; }
public string Toy { get; set; }
public string getName()
{
return Name;
}
}
Я использую эти классы вдругой, более сложный класс, который в основном имеет следующую структуру:
class MasterClass
{
public string Name;
public string Job;
public string Toy;
private ObservableCollection<Adult> ListOfAdults;
private ObservableCollection<Child> ListOfChildren;
private ObservableCollection<Human> CurrentList; // Will point to one of the above list
public void InitiateLists()
{
// Populate above lists with data
}
public Human CurrentHuman;
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults);
}
public void ManageChildren()
{
CurrentList = new ObservableCollection<Human>(ListOfChildren);
}
public void setOtherHuman()
{
// Sets CurrentHuman as another adult/child according to currently managed list
}
public void SetManager(string newType)
{
switch (newType)
{
case "adult":
ManageAdults();
break;
case "child":
ManageChildren();
break;
}
}
void UpdateInfo()
{
// Set Name and Toy/Job according to currently managed human
}
void PrintInfo()
{
// Print Name and Toy/Job according to currently managed human
}
}
Это каркас моей текущей реализации, с аспектами, которые я не могу изменить из-за других ограничений.В этом классе я хочу, чтобы методы PrintInfo () и UpdateInfo () вели себя по-разному, в зависимости от того, является ли CurrentHuman взрослым или потомком.
До сих пор
Мне удалось заставить его работать с swich-case в обоих методах и некоторых приведениях.Вот так:
void UpdateInfo(string currentType)
{
Name = CurrentHuman.getName();
switch (currentType)
{
case: "adult":
Job = ((Adult) CurrentHuman).Job;
break;
case: "child":
Toy = ((Child) CurrentHuman).Toy;
break;
}
}
Хотя это действительно не идеально.В моем реальном дизайне у меня намного больше типов и других методов, которые ведут себя по-разному в зависимости от типа CurrentItem.Так что теперь я тону в распределительных коробках.Это делает мой код запутанным, дублирующимся и очень сложным в обслуживании.
Возможное решение с интерфейсами
Поскольку я только что обнаружил их, я подумал, что могу использовать интерфейсы.Я сделал все возможное, но не смог найти решение для работы.
Я представлял себе простой интерфейс, подобный так:
public interface IUpdater
{
void UpdateData(); // Takes the values from CurrentHuman and store them in the private members Name and Job/Toy depending on current type.
void Print();
}
Я также реализую свой интерфейс двумя различными способами:
class AdultUpdater : IUpdater
{
public void Print()
{
// Print Adult stuff only
}
public void UpdateData()
{
// Update Adult data only.
}
}
и аналогичным class ChildUpdater : IUpdater
.Они оба реализуют специальный код для ребенка / взрослого.
Если я объявлю private IUpdater Updater
личным членом моего мастер-класса, это позволит мне изменить мои методы ManageAdult()
и ManageChildren()
следующим образом:
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults); // Same as before
Updater = new AdultUpdater(); // Specify implementation to use
}
(аналогично для ManageChildren()
).
Затем я могу блестяще реализовать свой UpdateInfo()
следующим образом:
void UpdateInfo()
{
Updater.UpdateData();
}
и мой PrintInfo()
метод следующим образом:
void PrintInfo()
{
Updater.Print();
}
Интерфейсыдействительно потрясающе!Ой, подождите ...
Новая проблема
Это кажется очень многообещающим.Моя проблема в том, что я не знаю, как реализовать код моих class AdultUpdater()
и class ChildUpdater()
.Точнее, эти два класса должны иметь доступ к закрытым членам MasterClass, а именно членам Name
, Job
и Toy
.UpdateData()
необходимо изменить их, а Print()
- отобразить их.Я чувствую себя настолько тупо застрявшим в этой точке, так близко к очень изящному решению.У кого-нибудь есть идеи, как доработать этот дизайн?
Спасибо, что прочитали ... Извините, если эту проблему можно было бы сократить до более краткого вопроса.У меня было чувство, что некоторые детали о моей текущей реализации были необходимы, чтобы получить подходящий ответ.