Je travaille sur une application ASP.NET MVC, et j'ai pris l'habitude de mettre ce qui semble être des getters utiles et pratiques dans mes classes de modèle / entité.
Par exemple:
public class Member
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string FullName
{
get { return FirstName + " " + LastName; }
}
public string FormattedPhoneNumber
{
get { return "(" + PhoneNumber.Substring(0, 3) + ") " + PhoneNumber.Substring(3, 3) + "-" + PhoneNumber.Substring(6); }
}
}
Je me demande si les gens pensent aux FullName
et aux FormattedPhoneNumber
getters.
Ils facilitent la création de formats de données standardisés dans l'application et semblent économiser beaucoup de code répété, mais on pourrait certainement affirmer que le format de données est quelque chose qui devrait être géré lors du mappage d'un modèle à un modèle de vue.
En fait, à l'origine, j'appliquais ces formats de données dans ma couche de service où je fais mon mappage, mais cela devenait un fardeau d'avoir constamment à écrire des formateurs, puis à les appliquer à de nombreux endroits différents. Par exemple, j'utilise "Nom complet" dans la plupart des vues, et avoir à taper quelque chose comme model.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);
partout semblait beaucoup moins élégant que de simplement taper model.FullName = entity.FullName
(ou, si vous utilisez quelque chose comme AutoMapper, potentiellement ne rien taper du tout).
Alors, où tracez-vous la ligne en ce qui concerne le formatage des données. Est-il «correct» de mettre en forme les données dans votre modèle ou est-ce une «odeur de motif»?
Remarque: je n'ai certainement pas de code HTML dans mon modèle. J'utilise des aides html pour cela. Je parle strictement de formatage ou de combinaison de données (et en particulier de données fréquemment utilisées).
la source
PhoneNumber
appartient probablement à sa propre classe (que j'ai maintenant implémentée). MaisFullName
c'est vraiment celui qui m'a motivé à écrire la question. Mais je suis intéressé à savoir si, en général, il est judicieux de mettre en forme / peigner les données, etc. dans le modèle pour les choses qui s'appliqueront à l'échelle de l'application. D'après les réponses ci-dessous, il semble que ce ne soit pas un anti-modèle, mais la décision doit être prise avec soin.Réponses:
Dans votre exemple, j'aime le
FullName
getter (pour toutes les raisons que vous avez données) mais je n'aime pas le getter FormattedPhoneNumber. La raison en est: ce n'est probablement pas si facile (une fois que vous avez des numéros de téléphone internationaux, etc.) et si vous placez la logique de formatage des numéros de téléphone dans une méthode deMember
, vous aurez probablement besoin de refactoriser (ou copier-coller caugh ) une fois que vous besoin d'un numéro de téléphone formaté pourInstitution
,Vendor
etc. aussi.EDIT: OMI, il serait préférable d'avoir une
PhoneNumber
classe avec unFormatted
getter.la source
String
classe, je suppose), vous "apprenez" à laString
classe comment formater les numéros de téléphone. Est-ce vraiment la responsabilité de laString
classe de connaître les numéros de téléphone? Je ne pense pas. Utilisées comme ça, les méthodes d'extension sont du sucre syntaxique pour laisser quelque chose qui n'est clairement pas orienté objet ressembler à ce qu'il était.PhoneNumber
classe. J'ai prévu de le faire de toute façon parce que j'ai aussi unePhoneType
propriété.PhoneNumber
une classe d'instance car les données sont nativesstring
. Il doit plutôt s'agir d'une classe statique avec des méthodes commepublic static string Format(string phoneNumber, PhoneNumberStyle style)
.Les choses que vous devez considérer lors de l'écriture de code: est-ce correct? Est-il lisible? Est-ce efficace? Est-il maintenable? Je dirais, comme @btilly l'a mentionné, que ce n'est pas maintenable en raison du formatage spécifique à la culture, mais la question semble être plus générale que cela.
L'utilisation d'accesseurs comme ceux-ci rend votre code plus lisible et, selon la façon dont vous l'utilisez, peut rendre les autres parties de votre code beaucoup plus propres. À mon avis, cela ne sent pas du tout. Cela commencerait à sentir si vous aviez des accesseurs de formatage pour tout type de chaîne que vous pourriez vouloir imprimer (
public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;
, etc.)Ou, pour le dire autrement, l'utilisation d'un motif ne fait pas automatiquement que votre code ait une "odeur de motif". Vous devez en abuser si vous voulez gagner cet attribut.
la source
Brise le principe de la responsabilité unique. Pourquoi ne pas faire une classe de numéro de téléphone, etc ...?
la source
FullName
cours?Pour votre exemple, je ne pense pas que ce soit trop important pour utiliser des formats spécifiques. C'est une ou deux et toutes les parties de l'application utilisent le même format.
Lorsque cette décision commencerait à s'effondrer, c'est lorsque vous avez les mêmes données à plusieurs endroits différents nécessitant des formats différents .
Si cela arrivait, je serais tenté de
Member
ramener la classe à:Et puis faites des adaptateurs différents pour chaque cible. Par exemple, supposons que les informations étaient requises au format CSV:
En supposant toujours que vous avez nettoyé les données afin qu'aucune virgule, etc. ne soit dans les chaînes.
L'adaptateur ne doit pas être une méthode d'extension, mais pour ce cas imaginaire, il semble convenir.
la source
over
autant de fois que cela, alors il y a un problème avec la conception.