Per rispondere a questa domanda devi distinguere tra fase di analisi delle informazioni e fase di progettazione; anche se i moderni metodi di ingegneria del software spesso li combinano, il modello (non deve essere un documento di 1073 pagine, può essere nella tua mente o nel codice) e il livello di dettaglio è diverso:
- Nella fase di analisi, il tuo modello corrisponderà strettamente alla realtà, il che significa che è un solo concetto
user
e alcune idee su quali dati su un utente è richiesto.
- Nella fase di progettazione, dipende da quali informazioni sull'utente la tua applicazione ha bisogno in varie situazioni e quanto è facile recuperare le informazioni.
Ad esempio, osservando il lato utente di Stack Exchange possiamo dedurre che:
- Spesso è sufficiente
<user name, avatar, reputation, gold medal count, silver medal count, bronze medal count>
(ad es. per visualizzare l'autore di un post o un commento).
- Per visualizzare i commenti, è sufficiente solo
user name
.
- Quando qualcuno visualizza un profilo utente, sono necessarie molte più informazioni:
<user name, avatar, reputation, gold medal count, silver medal count, bronze medal count, all questions, all answers, all comments, all badges, reputation changes>
.
- Quando un utente effettua l'accesso, sono necessarie le informazioni di autenticazione e la sessione del browser; ma questi non dovrebbero assolutamente essere mostrati nelle informazioni dell'autore.
Quindi qui, concettualmente, abbiamo quattro diverse classi User
. Potremmo anche optare per utilizzare <user name, avatar, reputation, gold medal count, silver medal count, bronze medal count>
-structure anche per l'autore dei commenti, poiché è comunque disponibile.
Puoi utilizzare l'ereditarietà per combinare i diversi tipi di UserInfo
, cioè:
class BasicUserInfo
{
public string Name { get; }
public Image Avatar { get; }
public int Reputation { get; }
public int GoldBadgeCount { get; }
public int SilverBadgeCount { get; }
public int BronzeBadgeCount { get; }
}
class UserProfileInfo: BasicUserInfo
{
public List<Post> Questions { get; }
public List<Post> Answers { get; }
public List<Comment> Comments { get; }
public List<Badge> Badges { get; }
public List<ReputationChange> Reputation { get; }
}
class UserAuthentication: BasicUserInfo
{
public string PlainTextPassword { get; } // Not really, I hope everyone knows why and
// how to do this correctly
}
class UserSession: BasicUserInfo
{
public List<Cookey> Cookey { get; set; }
public UserAuthentication Authentication { get; }
}
E quindi utilizzare qualche tipo di repository per trovare oggetti UserInfo
, ad esempio:
class UserRepository {
public UserProfileInfo FindUserProfile(BasicUserInfo user)
{
// …
}
public UserSession FindLoggedInUsers(BasicUserInfo user)
{
// …
}
}
Il repository utilizza deliberatamente la classe base comune, BasicUserInfo
, per trovare gli oggetti UserInfo estesi, poiché:
- consente di utilizzare qualsiasi tipo di
UserInfo
-object (i.e BasicUserInfo
e tutte le estese% varianti diUserInfo
) per cercare un esteso UserInfo
-oggetto;
- Sono diffidente nell'usare una stringa o int come ID utente, poiché dimentico le informazioni sul tipo
significa che possiamo confondere una stringa o int che contiene qualcosa di completamente diverso con una contenente
user id
(ad esempio se (UserRepository r, BasicUserInfo u) => r.FindUserProfile(u.BronzeBadgeCount)
dove supportato, darebbe risultati sorprendenti.)
TL; DR
A seconda di ciò che richiede l'applicazione, usa class User
leggero,% pesante% co_de o usa diversi tipi di class User
. Se utilizzi diversi tipi di UserInfo
, puoi utilizzare un repository e la classe base comune leggera UserInfo
per trovare il BasicUserInfo
esteso.