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> Le code ci-dessous doit démontrer: p> if (response.PolicyType == Enumerations.PolicyType.Motor)
{
lblDescription.Text = response.Policy.Description;
...
}
13 Réponses :
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;};
}
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?
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». P>
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) ....
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
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;
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.
Votre réponse peut-elle contenir une motorpolicy ou une maisonpolicypolicy ou, peut-elle contenir une de chacune? P>
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. P>
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.
Ma pensée immédiate est d'aller pour:
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
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 code> et cela fonctionne de toute façon. Vous avez le choix de rester avec le test lorsqu'il s'agit de lblcontents code> (Nasty dans la plupart des cas), avoir ménagepolicy renvoyer une chaîne vide pour Contenu Code> (Eh bien, il devrait b> effacer ce bit du formulaire) ou avoir une méthode abstraite () code> 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.
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;
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: p> 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). P> P>
Je suis d'accord avec les contrôles d'interface utilisateur.
Peut-être que je ne comprends pas la question mais j'utiliserais simplement l'héritage
définir la politique comme p>
politique de la classe publique
{
Description publique des chaînes {Obtenir; ensemble;}
Détails de la chaîne publique {obtenir; set;} p> et appelez par p> 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. P> P>
Une option est d'ajouter un membre à la stratégie code> qui synthétise toutes les propriétés pertinentes de la classe dérivée pour fournir un résumé: Ceci centralise la logique et fait Le code d'interface utilisateur simple: p> 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: p> 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). P> P>
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;
...
}
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;
}
Eh bien, je n'aime pas les classes abstraites, donc je suis allé avec une interface pour la stratégie puis nous héritons de créer motorpolicy p> 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. P> ceci pourrait facilement être modifié pour ne pas utiliser la liste et nous pouvons nous débarrasser de la surcharge Affichage. p> p>