Estoy trabajando en una aplicación ASP.NET MVC, y me he acostumbrado a poner lo que parecen útiles y convenientes captadores en mis clases de modelo / entidad.
Por ejemplo:
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); }
}
}
Me pregunto si la gente piensa en los FullName
y los FormattedPhoneNumber
captadores.
Facilitan la creación de formatos de datos estandarizados en toda la aplicación, y parecen guardar una gran cantidad de código repetido, pero definitivamente se podría argumentar que el formato de datos es algo que debe manejarse en el mapeo de modelo a modelo de vista.
De hecho, originalmente estaba aplicando estos formatos de datos en mi capa de servicio donde hago mi mapeo, pero se estaba volviendo una carga tener que escribir constantemente formateadores y luego aplicarlos en muchos lugares diferentes. Por ejemplo, utilizo "Nombre completo" en la mayoría de las vistas, y tener que escribir algo parecido en model.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);
todo el lugar parece mucho menos elegante que simplemente escribir model.FullName = entity.FullName
(o, si usa algo como AutoMapper, potencialmente no escribir nada).
Entonces, ¿dónde trazas la línea cuando se trata de formatear datos? ¿Está "bien" formatear los datos en su modelo o es un "olor a patrón"?
Nota: Definitivamente no tengo ningún html en mi modelo. Yo uso html helpers para eso. Estoy hablando estrictamente de formatear o combinar datos (y especialmente datos que se usan con frecuencia).
fuente
PhoneNumber
probablemente pertenece a su propia clase (que ahora he implementado). PeroFullName
fue realmente el que me motivó a escribir la pregunta. Pero estoy interesado en averiguar si, en general, tiene sentido incluir el formato / peinado de datos, etc. en el modelo para las cosas que se aplicarán en toda la aplicación. De las respuestas a continuación, parece que esto no es un antipatrón, pero la decisión debe tomarse con cuidado.Respuestas:
En su ejemplo, me gusta el
FullName
getter (por todas las razones que ha dado) pero no me gusta el getter FormattedPhoneNumber. La razón es: probablemente no es tan fácil (una vez que tenga los números internacionales de teléfono, etc.) y si se coloca la lógica para formatear números de teléfono en un método deMember
, lo más probable es que tendrá que refactor (o copiar y pegar caugh ) una vez que se también necesita un número de teléfono con formatoInstitution
,Vendor
etc.EDITAR: OMI sería mejor tener una
PhoneNumber
clase con unFormatted
getter.fuente
String
clase, supongo), usted "enseña" a laString
clase cómo formatear números de teléfono. ¿Es realmente responsabilidad de laString
clase saber acerca de los números de teléfono? No lo creo. Usados así, los métodos de extensión son azúcar sintáctica para dejar que algo que claramente no está orientado a objetos se vea como lo fue.PhoneNumber
clase. He estado planeando hacer eso de todos modos porque también tengo unaPhoneType
propiedad.PhoneNumber
una clase de instancia porque los datos son nativosstring
. Más bien, debería ser una clase estática con métodos comopublic static string Format(string phoneNumber, PhoneNumberStyle style)
.Las cosas que debe tener en cuenta al escribir código: ¿es correcto? ¿Es legible? ¿Es eficiente? ¿Es mantenible? Yo diría, como @btilly mencionó, que no se puede mantener debido al formato específico de la cultura, pero la pregunta parece ser más general que eso.
El uso de accesores como estos hace que su código sea más legible y, dependiendo de cómo lo use, puede hacer que otras partes de su código sean mucho más limpias. En mi opinión, eso no huele en absoluto. Comenzaría a oler si tuviera formateadores para cualquier tipo de cadena que desee imprimir (
public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;
, etc.)O, para decirlo de otra manera, el uso de un patrón no hace que su código tenga automáticamente "olor a patrón". Necesitas abusar de él si quieres ganar ese atributo.
fuente
Rompe el principio de responsabilidad única. ¿Por qué no hacer una clase de número de teléfono, etc.?
fuente
FullName
clase?Para su ejemplo, no lo veo como un gran problema para usar formatos específicos. Es una o dos y todas las partes de la aplicación usan el mismo formato.
Donde esa decisión comenzaría a romperse es cuando tienes los mismos datos yendo a varios lugares diferentes que requieren diferentes formatos .
Si eso sucediera, me vería tentado a
Member
devolver la clase a:Y luego haga diferentes adaptadores para cada objetivo. Por ejemplo, suponga que la información se requiere en formato CSV:
Siempre suponiendo que haya desinfectado los datos para que no haya comas, etc., en las cadenas.
El adaptador no tiene que ser un método de extensión, pero para este caso imaginario parece encajar.
fuente
over
tantas veces como eso, entonces hay algo mal con el diseño.