C# 组织课堂。。。最佳实践?
假设我有一门课,如下所示C# 组织课堂。。。最佳实践?,c#,class,C#,Class,假设我有一门课,如下所示 class FootballPlayer { public string Name { get; set; } public string TeamName { get; set; } public int CareerGoals { get; set; } public int CareerAssists { get; set; } public int CareerPa
class FootballPlayer
{
public string Name { get; set; }
public string TeamName { get; set; }
public int CareerGoals { get; set; }
public int CareerAssists { get; set; }
public int CareerPasses { get; set; }
public int SeasonGoals { get; set; }
public int SeasonAssists { get; set; }
public int SeasonPasses { get; set; }
public int CurrentMatchGoals { get; set; }
public int CurrentMatchAssists { get; set; }
public int CurrentMatchPasses { get; set; }
}
但我想把它组织得更好,所以我该怎么做呢。当时我试过这样的方法-
class CareerDetails
{
public int Goals;
public int Assists;
public int Passes;
}
class CurrentMatchDetails
{
public int Goals;
public int Assists;
public int Passes;
public bool IsCaptain;
}
class GeneralDetails
{
public string Name;
public string TeamName;
}
class SeasonDetails
{
public int Goals;
public int Assists;
public int Passes;
public int MatchesPlayed;
}
class FootballPlayer
{
public CurrentMatchDetails CurrentMatchDetails { get; set; }
public SeasonDetails SeasonDetails { get; set; }
public CareerDetails CareerDetails { get; set; }
public GeneralDetails GeneralDetails { get; set; }
}
有几件事我不喜欢
- 我必须公开课程(季节细节、职业细节等)
- 在实例化FootballPlayerClass之后,我必须分别实例化所有这些类
FootballPlayer
类上实现INotifyPropertyChanged
。通过使用上述方法,我将不得不在所有类(如CareerDetails
等)上安装INPC。那么,我应该怎么做,还是应该坚持使用现有的
我可能有另一个名为“足球队”的基类,它也可能有一个名为CurrentMatchDetails的子类-它可能看起来像这样
class CurrentMatchDetails
{
public double TimeElapsed;
public string RefereeName;
}
因此,我应该能够访问像teamObject.CurrentMatchDetails.ReferenceName或playerObject.CurrentMatchDetails.Goals这样的属性 您应该创建一个
StatDetails
对象:
class FootballPlayer
{
public FootballPlay()
{
CareerStats = new StatDetails();
SeasonStats = new StatDetails();
CurrentStats = new StatDetails();
}
public string Name { get; set; }
public string TeamName { get; set; }
public StatDetails CareerStats { get; set; }
public StatDetails SeasonStats { get; set; }
public StatDetails CurrentStats { get; set; }
}
class StatDetails
{
public int Goals { get; set; }
public int Assists { get; set; }
public int Passes { get; set; }
}
这样,您只需在两个类上实现INotifyPropertyChanged
我可能有另一个名为“足球队”的基类,它也可能有一个名为CurrentMatchDetails的子类
首先,名为FootBallTeam
的类不应该有名为CurrentMatchDetails
的子类。继承不是一种代码共享机制,而是根据物理世界建模。CurrentMatchDetails
aFootballTeam
?我看没有办法。此类模型的继承工作:
class FootballPlayer
{
}
class StarPlayer : FootballPlayer
{
}
这里的StarPlayer
是一个FootballPlayer
,因此足球运动员的所有这些属性也应该在明星球员身上可用。您应该使用作文,请在此处阅读更多内容:。在您的情况下,FootBallTeam
应该是CurrentMatchDetails
上的属性
我没有比Ed的答案更好的答案了(对他来说+1),我只想进一步充实他的答案
public class PlayerStat //Add 'Player' to name since stats can be for tourneys too
{
public int Goals { get; set; }
public int Assists { get; set; }
public int Passes { get; set; }
}
public class PlayerCurrentMatchStat : PlayerStat
{
public bool IsCaptain { get; set; }
}
public class PlayerSeasonStat : PlayerStat
{
public int MatchesPlayed { get; set; }
}
public class PlayerCareerStat : PlayerStat
{
}
//And your football player goes like this:
class FootballPlayer
{
public FootballPlay()
{
CurrentStats = new CurrentStat();
SeasonStats = new SeasonStat();
CareerStats = new CareerStat();
}
public string Name { get; set; }
public string TeamName { get; set; }
public PlayerCurrentMatchStat CurrentMatchStat { get; set; }
public PlayerSeasonStat SeasonStat { get; set; } //no need of naming 'Player'
public PlayerCareerStat CareerStat { get; set; } //inside Player class
}
如果某些类的可见性困扰您,您可以通过将它们推送到某个特定的命名空间来保护它。最后,一支足球队即使不参加比赛,也仍然是完全有效的实体。以这种方式建模:
class FootballTeam
{
// all what makes a good unit
}
class FootballMatch
{
public FootBallTeam Team1 { get; set; }
public FootBallTeam Team2 { get; set; }
public double TimeElapsed { get; set; }
public string RefereeName { get; set; }
}
有道理。现在就这样称呼它:
FootballMatch currentMatch = new FootballMatch(...whatever
提醒:上面的设计还可以,但还是有点臭。为什么
足球运动员
会有PlayerCurrentMatchStat
?一个足球运动员即使坐在板凳上也是一个完美的球员。如果他不在比赛中,你可能会使它无效。球员赛季状态也一样-如果是,是哪个赛季?我会完全重新设计它,imo稍微复杂一点,但更符合逻辑
public interface Stat //common interface which can be for tourneys, matches etc too
{
int Goals { get; set; }
int Assists { get; set; }
int Passes { get; set; }
}
//You might want to break this interface further to fit in other specific stats
//like player stat, match stat etc.
//Also making it an interface rather than base class is better, you shouldnt have
//2 different entities like PlayerStat and MatchStat share a common base class
public class PlayerStat : Stat //can be career stat, single match stat etc;
{ //depends on context where you call it
public int Goals { get; set; }
public int Assists { get; set; }
public int Passes { get; set; }
}
//another example
public class MatchStat : Stat
{
public int Goals { get; set; }
public int Assists { get; set; }
public int Passes { get; set; }
public int Viewership { get; set; }
}
class Team
{
// all what makes a good unit
}
class Match
{
public Team Team1 { get; set; }
public Team Team2 { get; set; }
public double TimeElapsed { get; set; }
public string RefereeName { get; set; }
public MatchStat Stat { get; set; } //a match has match stat
}
//provide a suitable constructor that takes a player and a match
public class PlayerMatchStat
{
public Player Player { get; set; }
public Match Match { get; set; }
public PlayerStat Stat { get; set; } //should return player's stat for this match
public bool IsCaptain { get; set; }
public int DistanceCompleted { get; set; }
}
//provide a suitable constructor that takes a player and a season
public class PlayerSeasonStat
{
public bool Player { get; set; }
public Season Season { get; set; } //have a season class
public PlayerStat Stat { get; set; } //should return player's stat for this season
public int RedCards { get; set; }
}
//and lastly
class Player
{
public Player()
{
//init work
}
public string Name { get; set; }
public PlayerStat CareerStat { get; set; } //just like match has match stat
public Team[] Teams { get; set; } //Team name shouldn't go within a player
//class, he could be in many teams.
//since player inherently has no match or season, we shall provide methods to query them
public PlayerMatchStat GetMatchStat(Match match)
{
return new PlayerMatchStat(match, this);
}
public PlayerSeasonStat GetSeasonStat(Season season)
{
return new PlayerSeasonStat(season, this);
}
}
在这里,遗产被谨慎地使用(在有保证的情况下),而用于产生良好效果的是组合。你可以将它们私有化,让足球运动员管理它们。使它们也是静态的。你可以创建一个create
方法来初始化它。欢迎来到地狱。。我们一直在等你的到来。你不会相信这一点,但这个问题只是众多问题中的第一个。我建议你要么用EF制作你的模型,打破分层结构的完美秩序,要么你可以加入我的行列,总有更多的空间:)@G.Y哇谢谢。实体框架可能正是我所需要的。现在只是通过教程来理解它。让我们看看我的小脑袋是否能处理另一个新概念。FWIW,StatsDetails
中的字段不能与INotifyPropertyChanged
或WPF一起使用。一般来说,OP需要适当的属性。这只是一个示例,但CareerDetails可能具有其他类不具备的属性,在这种情况下,这不起作用。用这种方法考虑的另一个问题是绑定将是什么样子。您需要绑定到子属性,即Text={Binding Path=CareerStats.Goals,Mode=TwoWay}
。这对你来说可能是个问题,也可能不是,但值得思考about@AnkurSharma我认为这里的重点是遵循规则。如果你想对较小的部分进行子类划分,在适当的地方创建基类,并在必要时对其进行子类划分。@AnkurSharma,那么这取决于个人品味。可以有一个大对象或多个小对象。由于有这么多不同的属性,它对于您的解决方案来说太具体了,因此没有最佳实践。或者,“最佳实践”是在项目、团队或组织中保持一致。我认为子类的意思类似于-mainClass.subClass.property,但它实际上与继承相关。同样,在FootballPlayer()的构造函数中,您是否应该使用(例如)new CareerStats()而不是new StatDetails()来实例化它们?哦,我明白了,您弄错了,哎呀。你两方面都是对的。是的,子类化意味着继承。你的意思是合成,是的,我会编辑打字复制粘贴错误:)@AnkurSharma如果你所有的应用程序都是关于“足球”的,那么我建议你从那里去掉所有的Football
关键字,让你的代码更具可读性和简短性。像Player
,Match
等。如果你也有HockeyTeam
s,那就不同了:)。顺便说一句,我认为你的设计可以再好一点。我会更新。抓住它。非常感谢。这很有帮助。我同意,我应该重新设计我的代码。我一定会听从你的建议。Thx,一个比下面更好的答案。@AnkurSharma类似地,你可以有PlayerTeamStat
(需要一个团队和球员)等等。重要的是你要理解流程(这就是为什么要详细阐述的原因:)总是思考现实世界。。