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之后,我必须分别实例化所有这些类
但我不确定这是否是最佳做法。我在考虑在足球运动员的班级中创建一个嵌入式班级

我将在WPF应用程序中使用该类,并将在我的
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
a
FootballTeam
?我看没有办法。此类模型的继承工作:

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
(需要一个团队和球员)等等。重要的是你要理解流程(这就是为什么要详细阐述的原因:)总是思考现实世界。。