我有一个设计问题,无法解决克利夫利。我敢肯定有一个不错的解决方案,但我不知道该如何实现。我仍然设法完成我的代码工作,但是结果很丑陋,我想学习更好的设计。
我竭尽所能提供最小的实现。因此,某些方面可能看起来很奇怪。我希望我能弄清楚自己。
所以首先,我有这些简单的类,它们都实现了相同的接口:
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是成人还是儿童。
在两种方法和某些强制转换中,我都设法使其采用夹心格式。像这样:
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
声明为MasterClass的私有成员,则可以这样更改我的方法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()
需要显示它们。在这一点上,我感到非常愚蠢,非常接近一个非常明智的解决方案。有人知道如何完成此设计吗?
谢谢您的阅读...很抱歉,如果可以将此问题简化为更简洁的问题。我觉得需要一些有关当前实现的细节才能获得合适的答案。
答案 0 :(得分:1)
正如我所见,您正在尝试“管理”您的人类。只是让他们自己做这项工作。 f.e.不要从经理/大师班打印并决定要打印什么,而要从人类那里获取打印的数据(即使只是部分,但不同的部分),也要将它们放到大师班中。
为您使用多态。他们(您的对象/人类)已经知道要打印或更新的内容,因此让他们来完成工作。尝试分散工作,而不是将所有工作都归为一类。
答案 1 :(得分:0)
这是我的建议,
您有一个与您的IHuman相对应的Human类,就像这样
public class Human : IHuman
{
public Human(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
然后,您的成人和儿童类将继承Human类并传回构造函数值。
public Adult(string name, string job) : base (name, job)
{
}
创建成人实例时,您将传入名称和工作,并且可以调用getName,因为它将继承自Human类。