Java/Android + Realmでスポーツ統計アプリを作ろうとしています。
次のクラスがあります。
Season
Player
Matches
シーズンには、そのシーズンをプレイしたすべてのプレーヤーの「リスト」が含まれ、プレーヤーには一致の「リスト」が含まれます。
私は現在、各クラスの属性として実際のリストを持っています。たとえばPlayerクラス:
public class Player{
String name;
Int wins;
Int losses;
List <Matches> matches;
}
.add関数を使用して、プレーヤーに新しい対戦を追加します。また、簡単にするためにRealmに関連する構文をいくつか削除しましたが、これはRealmObjectになります。
これを行うより良い方法はありますか?シーズンに関連するすべての試合を取得したい場合など、この実装に問題があることに気付きました。私は各プレーヤーを通過し、重複を説明する必要があります。同様に、シーズンに関係なくすべてのプレーヤーを表示したい場合。
より良い方法は何でしょうか?
編集:これを明確にするには、戦闘スポーツであり、オブジェクトを他のオブジェクトに関連付ける方法を探しています。アプリの本当の目的は、コーチが選手を追跡するための小さなレベルにあります。プレイヤーは本質的にチームです。ユーザーはプレイヤーの統計にかなり集中しています。以下は、UFCを例にしたレイアウトです。
アプリは年のリストを開きます。リストから2019を選択するとします。これにより、2019で一致したすべてのプレーヤーのリストが開きます。ハビブを選びます。次に、その年の彼の統計とマッチを表示します(日付を変更して、必要に応じて過去3年間またはライフタイムのビューに変更できるようにするオプションがあります)。次に、特定の一致を選択して、その詳細を表示できます。
現在の実装の問題は、範囲の変更です。たとえば、ユーザーがシーズンに関係なくすべてのプレーヤーを表示したい場合は、試合が表示される範囲を変更します。
正直なところ、多くのものが欠けているように感じます。
考えることをあなたに与えるためだけに。この構造から引き出すことができるエンティティはさらに多くあります。 SportsAssociation、Match、Teamなど、一部は読み取り/書き込みエンティティになります。 SeasonRecordのように、一部は基本的にクエリのラッパーになります。
提案されたデザインについて私が知っていることの1つは、1つのチームがマッチを所有していないことです。マッチは2つの異なるチームを参照する独自のエンティティであり、スコアと、場合によっては日付を含みます。特定のTeamの統計情報が必要な場合は、チームを参照して一致のコレクションを持つことができるため、TeamRecordが役立ちます。 TeamRecordクラスも読み取り専用で、統計を計算するためのパブリックメソッドを公開します。
思考の糧としてのほんの数行のコード:
nba = new SportsAssociation("National Basketball League", "NBA");
rival1 = new Team("Detroit Pistons");
rival1.addPlayerToRoster(new Player(...));
rival1.addPlayerToRoster(new Player(...));
...
rival2 = new Team("Chicago Bulls");
rival2.addPlayerToRoster(new Player(...));
rival2.addPlayerToRoster(new Player(...));
...
nba.addTeam(rival1);
nba.addTeam(rival2);
season = nba.createSeason("2020-2021", beginDate, endDate);
match = season.getMatch(1);
// .. play match
seasonRecord = season.getSeasonRecord(rival1);
teamRecord = season.getTeamRecord(rival1);
seasonLeader = seasonRecord.getLeader(); // Returns rival1 of course ;-)
拡大して Greg Burghardt 視覚的な支援(およびlooselyの例としてカレッジフットボールを使用して)の素晴らしい答え:
public class Association {
List<Conference> conferences;
}
public class Conference {
List<Team> teams;
List<Season> pastSeasons;
Season currentSeason;
}
public class Season {
List<Match> matches;
TeamRankings teamRankings;
PlayerRankings playerRankings;
}
public class Team {
List<Player> roster;
}
public class Match {
Team team1;
Team team2;
Result result;
}
public class Result extends Record {
}
public class Player {
}
public abstract class Record {
}
public class PlayerRankings extends Record {
}
public class TeamRankings extends Record {
}
あなたがしていることは、最初に「ドメイン」を一種の独立として記述しようとしています。何が何を含んでいるか、何がどのデータ要素を含んでいるかなどを把握しようとする.
このモデルがいくつかのメトリックスから「良い」かどうか疑問に思っていると思います。
次に、これが何に使用されるのかを後から考えて、「編集」として言及します。
モデリングはまったく逆の方法です。何にも「客観的」な(しゃれた口実)モデルはありません。オブジェクトは「現実」を反映していません。少なくともこの方法は反映されていません。 要件をモデル化する必要があります。要件のないモデルはありません。
実演させてください。あなたが言うなら:
アプリは年のリストを開きます。
私は言うでしょう:
interface Years {
fun list(): View
}
それからあなたは言う:
リストから2019を選択するとします。これにより、2019で一致したすべてのプレーヤーのリストが開きます。
わかりました、ここに行きます:
interface Year {
fun listPlayers(): View
}
ここで、実際に「View」を返すことができないいくつかの技術的な理由がありますが、ここの例はモデリング部分です。要件から始めて、そこに必要なものを書き留めます。インスタンス変数やデータなど、その他すべては完全に二次的なものであり、オブジェクト指向の観点からはそれほど重要ではありません。
私はあなたがそうであるように、これは人々がそれをする方法ではないことを知っています、そしてAndroidアプリケーションは理由によりこのように書かれていません。しかし、これはオブジェクト指向であり、適切な、長いお客様の要件に対応した長期保守可能な設計は次のようになります。