7
votes

C # Héritage de classe

Je travaille avec assurance et j'ai deux types de politiques différents - moteur et ménage, représentés par deux classes différentes, moteur et ménage.

Tous deux ont plusieurs bits de données en commun, donc les deux hériteraient d'une autre classe appelée politique. Lorsqu'un utilisateur se connecte à l'application, ils pourraient avoir un moteur ou une stratégie de ménage. L'application doit donc afficher les informations génériques et les informations propices au moteur ou au ménage. Pour encapsuler tout cela, j'ai un objet de réponse qui a à la fois un élément moteur et un membre du ménage, comme indiqué ci-dessous: p> xxx pré>

Le code ci-dessous doit démontrer: p>

if (response.PolicyType == Enumerations.PolicyType.Motor) 
{
    lblDescription.Text = response.Policy.Description;
    ...
}


0 commentaires

13 Réponses :


0
votes

Définissez l'interface de stratégie et mettez-la dans vos deux classes de stratégie

Interface IPolicy{
    int Reg {get;set;};
    string Contents {get;set;};
}

MotorPolicy : Policy,IPolicy {

 string IPolicy.Contents 
     {get;set;};


 int IPolicy.Reg 
     {get;set;};

}

HouseholdPolicy : Policy , IPolicy {
 string IPolicy.Contents 
     {get;set;};


 int IPolicy.Reg 
     {get;set;};
}


4 commentaires

Il a une base de base appelée politique, à la place d'une interface ne changerait rien.


Ce n'est pas vraiment comment je comprends bien Oo Design. Les politiques des ménages n'ont pas de numéro de REG, et les politiques motrices n'ont pas de contenu. Par conséquent, la conception est trompeuse


Ok .. alors il peut peut-il définir comme ça une autre façon .. Motorpolicy: politique, Ipolicy


Ramesh, comment fonctionnerait-il hériter de la classe de base et de l'interface?



0
votes

La solution la plus simple consisterait à mettre en œuvre une interface avec une propriété de description et une propriété "Contenu", puis dans la classe de stratégie de votre moto, crée un "contenu" factice «Contenu» qui renvoie «REG».


0 commentaires

5
votes

Votre réponse n'a besoin que d'un type de stratégie, vous pouvez ensuite stocker un type motorpolicy ou ménagepolicy.

Alors votre réponse doit simplement vérifier le type de données P>

if (response.Policy is MotorPolicy) ....


2 commentaires

Notez que si vous poursuivez ce chemin, vous pouvez finir par écrire beaucoup d'instructions «si / puis» ou «commutateur» pour gérer le traitement en fonction du type. Dans ce cas, vous voudrez envisager un motif appelé "Remplacer le conditionnel avec Stratgy" informit.com/articles/article.aspx?p=1398607&eqnum=2


Il pourrait également créer un dictionnaire > qui mappe chaque type de stratégie à une méthode de gestionnaire séparé.



1
votes
lblDescription.Text = response.Policy.Description;
IHasReg hasReg = response.Policy as IHasReg;
if (hasReg != null) lblReg.Text = hasReg.Reg;
IHasContents hasContents = response.Policy as IHasContents;
if (hasContents != null) lblContents.Text = hasContents.Contents;

2 commentaires

C'est ce que j'ai pensé commencer, mais je n'aiimais tout simplement pas comment mon félicitationPolicy contiendrait REG et la motorpolicy contiendrait des contenus. J'aimerais vraiment avoir un objet de politique qui, basé sur les données obtenues, n'aurait qu'un ou l'autre.


@Chris - Je regarderais cela l'inverse. Votre réponse a besoin d'une description, d'un REG et de contenus, donc toute mise en œuvre de la politique devrait fournir ces données, d'où l'interface. Les implémentations concrètes renvoient délibérément String.empty dans les champs qui ne s'appliquent pas à ce type de politique.



0
votes

Votre réponse peut-elle contenir une motorpolicy ou une maisonpolicypolicy ou, peut-elle contenir une de chacune?

Si vous avez affaire à l'un ou à l'autre, créez un type de base que les deux classes héritées qui définissent les propriétés communes. Lorsque vous produisez les propriétés communes, jetez simplement la stratégie comme type de base et utilisez cela.


1 commentaires

Il contient à la fois un ménagepolicy et une motorpolicy, mais je dois ensuite faire référence à ma description comme réponse.Motorpolicy.description et réponse.houseHoldPolicy.description pour les propriétés communes. Je veux vraiment juste avoir une réponse.policy.description, donc je ne suis pas presque du code duplication.



0
votes

Ma pensée immédiate est d'aller pour: XXX


7 commentaires

Pourquoi favorisez-vous des champs explicites, etc. Au lieu d'utiliser une classe de base générique?


Je ne le fais pas, mais je ne suis pas aussi familier avec des génériques, en particulier les utiliser comme classes de base, et je ne pouvais pas obtenir cette solution pour travailler. Savez-vous comment??


@LUCERO, je ne discuterais pas pour les génériques ici (sur la base de ce que nous connaissons du problème), car, à l'heure actuelle, de savoir ce que les points communs que je peux voir comme utile en réponse dépend de la communalité de la politique, et si je devais avoir Réponse Où T: Politique Il suffit de tirer de la réponse pour fournir les extras nécessaires. Vraiment, une classe de base générique n'ajoute pas beaucoup d'extra, puis il bloque tout polymorphisme d'exécution.


Si je suis allé avec cette solution, je ne voudrais donc pas avoir deux types d'objets de réponse différents, je serais donc de retour dans la situation que je suis maintenant, sauf avec la réponse au lieu de la politique.


@Jon, c'était le problème que j'ai rencontré quand j'ai essayé une solution générique.


Non, vous pouvez appeler intervention.policy.description et cela fonctionne de toute façon. Vous avez le choix de rester avec le test lorsqu'il s'agit de lblcontents (Nasty dans la plupart des cas), avoir ménagepolicy renvoyer une chaîne vide pour Contenu (Eh bien, il devrait effacer ce bit du formulaire) ou avoir une méthode abstraite () est remplacée dans chaque cas (semble être trop excédentaire ici et plus de travail que sa valeur, mais dans certains cas similaires Cela peut être la voie à suivre, par exemple si vous aviez besoin de chacun pour produire une partie de HTML pour une application Web).


Cela dit, vous remarquerez qu'il y a encore un peu de commutation et si-d'autre se passe dans la méthode d'usine. L'avantage si elle pousse tout en un seul endroit, plutôt que de joindre le reste du code.



0
votes

J'essaierais quelque chose comme ceci:

lblDescription.Text = response.SelectedPolicy.Description;

if (SelectedPolicy is MotorPolicy)
    lblReg.Text = ((MotorPolicy)response.SelectedPolicy).Reg;

else if (SelectedPolicy is HouseholdPolicy)
    lblContents.Text = ((HouseholdPolicy)response.SelectedPolicy).Contents;


0 commentaires

5
votes

Chaque descendant de la politique (maintenant vous en avez deux, vous pourriez avoir plus à l'avenir, non?) Devrait avoir leurs propres contrôles d'interface utilisateur qui "savent" comment traiter les informations de la politique. La même approche peut être utilisée pour d'autres choses, telles qu'un "contrôleur" pour les objets de stratégie, etc.

La réponse peut ensuite être rendue générique: xxx

Alternativement, vous pourrait avoir une approche plus générique qui utilise la réflexion pour afficher les informations, mais celles-ci sont généralement moins "sexy" dans leur apparition et leur convivialité (pensez à la grille de propriété dans le concepteur VS).


1 commentaires

Je suis d'accord avec les contrôles d'interface utilisateur.



0
votes

Peut-être que je ne comprends pas la question mais j'utiliserais simplement l'héritage

définir la politique comme

politique de la classe publique { Description publique des chaînes {Obtenir; ensemble;} Détails de la chaîne publique {obtenir; set;} xxx

et appelez par xxx

NOTE I Mettre Reg / Contents sous forme de détail de champ car ils sont tous les deux Types de chaîne. Si l'on était une chaîne int Vs, ils devraient être effectués séparément.


0 commentaires

1
votes

Une option est d'ajouter un membre à la stratégie qui synthétise toutes les propriétés pertinentes de la classe dérivée pour fournir un résumé: xxx

Ceci centralise la logique et fait Le code d'interface utilisateur simple: xxx

que la mise en œuvre de base sacrifie la possibilité de formater les sous-sections séparément. Vous pouvez surmonter que, en exposant le résumé en tant que collection de chaînes: xxx

si vous souhaitez afficher les détails des classes dérivées de manière fondamentalement différente, vous devrez embrasser La logique conditionnelle dans la couche d'interface utilisateur (par exemple, vous pouvez énumérer le contenu de la stratégie de ménage dans une table, mais montrer une image numérisée pour l'enregistrement de la stratégie de moteur).


0 commentaires

1
votes

Utilisez le modèle de modèle:

Créer une classe de base appelée Politique avec une méthode de résumé virtuelle GET pour déterminer la description de la stratégie. p>

if (response.Policy != null)        
{       
    lblDescription.Text = response.Policy.Description;       
    ...       
}    


0 commentaires

0
votes

Le vôtre est un exemple unique de "condition de refactorisation au polymorphisme" [Fowler].

et ensuite votre méthode doit accepter l'objet approprié et faire comme ci-dessous: p>

public void Update(IPolicy policy)
{
        lblDescription.Text = policy.Description;
        lblReg.Text = .Reg;

}


0 commentaires

0
votes

Eh bien, je n'aime pas les classes abstraites, donc je suis allé avec une interface pour la stratégie xxx

puis nous héritons de créer motorpolicy xxx

Ensuite, pour la réponse, j'ai changé la politique en une liste de la chance de pouvoir avoir ou non plus. Maintenant, nous avons déchargé le traitement de l'affichage des données à la stratégie spécifique elle-même. xxx

ceci pourrait facilement être modifié pour ne pas utiliser la liste et nous pouvons nous débarrasser de la surcharge Affichage.


0 commentaires