La classe est meilleur?[fermé]
-
09-06-2019 - |
Question
La classe dont le design est mieux et pourquoi?
public class User
{
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee : User
{
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member : User
{
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
OU
public class User
{
public String UserId;
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee
{
public User UserInfo;
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member
{
public User UserInfo;
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
La solution
La question est tout simplement répondu en reconnaissant que l'héritage des modèles de type "EST-UN" de la relation, tandis que l'adhésion des modèles "A-UN" de la relation.
- Un employé EST UN utilisateur
- Un employé A UN userinfo
Laquelle est la bonne?C'est votre réponse.
Autres conseils
Je n'aime pas soit une.Ce qui se passe quand quelqu'un est à la fois un membre ou un employé?
Demandez-vous ce qui suit:
- Voulez-vous un Employé modèle EST un Utilisateur?Si oui, a choisi d'héritage.
- Voulez-vous un Employé modèle A un Utilisateur de l'information?Si oui, utiliser la composition.
- Sont des fonctions virtuelles entre l'Utilisateur (info) et l'Employé?Si donc, utiliser l'héritage.
- Un Employé peut-il avoir plusieurs instances de l'Utilisateur (info)?Si oui, utiliser la composition.
- Est-il judicieux d'affecter un Employé de l'objet à un Utilisateur (info) objet?Si donc, utiliser l'héritage.
En général, s'efforcer de modéliser la réalité de votre programme simule, sous les contraintes de la complexité du code et de l'efficacité.
Je ne pense pas que la composition est toujours mieux que de l'héritage (juste en général).Si des Employés et des Membres sont vraiment les Utilisateurs, et ils sont mutuellement exclusifs, alors la première conception est meilleure.Considérez le scénario où vous avez besoin d'accéder le nom d'utilisateur de l'Employé.À l'aide de la deuxième conception, vous aurait:
myEmployee.UserInfo.UserName
ce qui est mauvais (loi de Déméter), de sorte que vous vous refactoriser à:
myEmployee.UserName
ce qui nécessite un petit méthode de l'Employé à déléguer à l'Utilisateur de l'objet.Tous ce qui est évité par la première conception.
Belle question, bien que pour éviter les distractions sur droit et mal J'avais envisager de demander pour les avantages et les inconvénients de chaque approche -- je pense que c'est ce que vous voulez dire par ce qui est meilleur ou pour le pire, et pourquoi.De toute façon ....
La Première Approche aka Héritage
Pour:
- Permet le comportement polymorphique.
- Est initialement simple et pratique.
Inconvénients:
- Peut devenir complexe ou maladroit au fil du temps si de plus le comportement et les relations sont ajoutés.
La Deuxième Approche aka Composition
Pour:
- Les cartes non-oop scénarios comme des tables relationnelles, structurée programmation, etc
- Est simple (pas forcément pratique) à progressivement développer les relations et le comportement.
Inconvénients:
- Pas de polymorphisme par conséquent, il est moins pratique à l'utilisation de l'information et de comportement
Des listes de ce genre + questions Jon Limjap mentionnés va vous aider à prendre des décisions et d'obtenir commencé, vous pouvez trouver ce que l' droit les réponses devraient avoir été ;-)
Vous pouvez aussi penser à l'Employé comme un rôle de l'internaute (Personne physique).Le rôle de l'Utilisateur peut changer dans le temps (l'utilisateur peut devenir chômeurs) ou un Utilisateur peut avoir plusieurs rôles en même temps.
L'héritage est beaucoup mieux quand il est réel "est-un" de la relation, par exemple Pomme - Fruit.Mais soyez très prudent:Cercle Ellipse n'est pas réel "est une" relation, parce que cirlce moins de "liberté" que l'ellipse (cercle est un état de l'ellipse) - voir: Cercle Ellipse problème.
Les vraies questions sont:
- Quelles sont les règles et les histoires d'utilisateurs derrière un utilisateur?
- Quelles sont les règles et les histoires d'utilisateurs derrière un employé?
- Quelles sont les règles et les histoires d'utilisateurs derrière un membre?
Ceux-ci peuvent être de trois entités indépendantes ou non, et qui permettra de déterminer si votre première ou de la deuxième conception, ou si un autre complètement différent de la conception est en ordre.
Aucun des deux n'est bon.Trop mutable état.Vous ne devriez pas être en mesure de construire une instance d'une classe qui n'est pas valide ou partiellement initialisé à l'état.
Cela dit, la deuxième est mieux, parce qu'il favorise la composition au cours de l'héritage.
En indiquant votre exigence/spec pourrait les aider à trouver le "meilleur design".
Votre question est trop "sujet-pour-lecteur-interprétation" à l'heure actuelle.
Voici un scénario, vous devriez penser à:
Composition (2ème exemple) est préférable si le même Utilisateur peut être à la fois un Employé et un Membre.Pourquoi?Parce que, pour deux instances (des Employés et des Membres) qui représentent le même Utilisateur, si l'Utilisateur des modifications des données, vous n'avez pas à mettre à jour dans les deux endroits.Seule l'instance d'Utilisateur contient toutes les informations de l'Utilisateur, et lui seul doit être mis à jour.Depuis que la fois des Employés et des Membres des classes contiennent la même instance d'Utilisateur, ils seront automatiquement les deux contiennent les informations mises à jour.
Plus de trois options:
Ont le
User
classe contiennent de l'information supplémentaire pour les employés et les membres, avec des champs non utilisés vide (leID
d'un particulierUser
indique si l'utilisateur est un employé, un membre, à la fois, ou quoi que ce soit).Avoir un
User
la classe qui contient une référence à unISupplementalInfo
, oùISupplementalInfo
est héritée parISupplementalEmployeeInfo
,ISupplementalMemberInfo
, etc.Le Code qui est applicable à tous les utilisateurs peuvent travailler avecUser
les objets de la classe, et le code qui avait unUser
référence pourrait avoir accès à un utilisateur des informations supplémentaires, mais cette approche permettrait d'éviter d'avoir à changerUser
si les différentes combinaisons des informations supplémentaires sont requises à l'avenir.Comme ci-dessus, mais qui ont le
User
classe contiennent une sorte de collection deISupplementalInfo
.Cette approche aurait l'avantage de faciliter l'ajout de propriétés à un utilisateur (par ex.parce qu'unMember
ai embauché).Lors de l'utilisation de l'approche précédente, on aurait à définir des classes différentes pour différentes combinaisons de propriétés;tournage d'un "membre" dans un "membre+client" aurait besoin d'un code différent de tourner un "employé" dans un "salarié+client".L'inconvénient de cette approche est qu'il serait plus difficile de se prémunir contre redondants ou l'incohérence des attributs (en utilisant quelque chose comme unDictionary<Type, ISupplementalInfo>
de détenir des informations supplémentaires qui pourraient travailler, mais semble un peu "encombrant").
J'aurais tendance à privilégier la seconde approche, en ce qu'elle permet l'agrandissement de mieux que l'héritage direct.De travail avec une collection d'objets plutôt qu'un seul objet peut être légèrement pénible, mais cette approche peut être mieux que les autres pour gérer l'évolution des besoins.