He estado pensando en esto yo también. Aquí están mis pensamientos sueltos hasta ahora, y me pregunto qué piensan los demás.
xAL (y su hermana, que incluye nombres personales, XNAL) es utilizado tanto por los servicios de geocodificación de Google como de Yahoo, lo que le da algo de peso. Pero dado que la misma dirección se puede describir en xAL de muchas maneras diferentes, algunas más específicas que otras, entonces no veo cómo xAL en sí es un formato aceptable para el almacenamiento de datos. Algunos de sus nombres de campo se podrían utilizar, sin embargo, pero en realidad el único formato básico que se puede utilizar entre los 16 países que mis compañía envía a es la siguiente:
enum address-fields
{
name,
company-name,
street-lines[], // up to 4 free-type street lines
county/sublocality,
city/town/district,
state/province/region/territory,
postal-code,
country
}
Eso es bastante fácil para trazar en una sola tabla de base de datos, permitiendo solo NULL en la mayoría de las columnas. Y parece que así es como Amazon y muchas organizaciones almacenan datos de direcciones. Entonces, la pregunta que queda es cómo debería modelar esto en un modelo de objetos que sea fácilmente utilizado por los programadores y por cualquier código GUI. ¿Tenemos un tipo base Address
con subclases para cada tipo de dirección, como AmericanAddress
, CanadianAddress
, GermanAddress
, etc.? Cada uno de estos tipos de direcciones sabría cómo formatear ellos mismos y, opcionalmente, sabría un poco sobre la validación de los campos.
También podrían regresar algún tipo de metadatos acerca de cada uno de los campos, tales como la estructura de datos siguiente pseudocódigo:
structure address-field-metadata
{
field-number, // corresponds to the enumeration above
field-index, // the order in which the field is usually displayed
field-name, // a "localized" name; US == "State", CA == "Province", etc
is-applicable, // whether or not the field is even looked at/valid
is-required, // whether or not the field is required
validation-regex, // an optional regex to apply against the field
allowed-values[] // an optional array of specific values the field can be set to
}
De hecho, en lugar de tener objetos de direcciones individuales para cada país, que podría tomar la un enfoque ligeramente menos orientado a objetos de tener un objeto Address
que evita.propiedades NET y utiliza un AddressStrategy
para determinar las reglas de formateo y de validación:
object address
{
set-field(field-number, field-value),
address-strategy
}
object address-strategy
{
validate-field(field-number, field-value),
cleanse-address(address),
format-address(address, formatting-options)
}
Al configurar un campo, que Address
objeto sería invocar el método apropiado en su AddressStrategy
objeto interno.
El motivo de utilizar un método SetField()
en lugar de propiedades con getters y setters es tal que es más fácil para el código establecer estos campos de forma genérica sin recurrir a sentencias de reflexión o cambio.
se puede imaginar el proceso va algo como esto:
- código de interfaz gráfica de usuario llama a un método de fábrica o algo parecido para crear una dirección sobre la base de un país. (El menú desplegable del país, entonces, es lo primero que el cliente selecciona, o tiene una buena conjetura preseleccionada para ellos según la información cultural o la dirección IP.)
- La GUI llama a
address.GetMetadata()
o un método similar y recibe una lista de las estructuras AddressFieldMetadata
como se describió anteriormente. Puede usar estos metadatos para determinar qué campos mostrar (ignorando aquellos con is-applicable
establecidos en false
), qué etiquetar esos campos (usando el miembro field-name
), mostrar esos campos en un orden particular y realizar una validación superficial, de nivel de presentación en esos datos (usando los miembros is-required
, validation-regex
y allowed-values
).
- La GUI llama al método
address.SetField()
utilizando field-number
(que corresponde a la enumeración anterior) y sus valores dados. El objeto Address
o su estrategia puede entonces realizar una validación avanzada de direcciones en esos campos, invocar a los limpiadores de dirección, etc.
Puede haber pequeñas variaciones respecto a lo anterior, si queremos hacer que el objeto en sí Address
se comportan como un inmutable objeto una vez que se crea. (Lo cual probablemente intentaré hacer, ya que el objeto Address
es realmente más como una estructura de datos, y probablemente nunca tenga ningún comportamiento verdadero asociado a sí mismo.)
¿Tiene algo de esto sentido? ¿Me estoy alejando demasiado de la ruta OOP? Para mí, esto representa un compromiso bastante sensato entre ser tan abstracto que la implementación es casi imposible (xAL) versus estar estrictamente predispuesto por los EE. UU.
Actualización 2 años más tarde: que finalmente terminó con un sistema similar a este y escribió sobre él en my defunct blog.
Creo que esta solución es el equilibrio correcto entre los datos heredados y el almacenamiento de datos relacionales, al menos para el mundo del comercio electrónico.
¿En qué país/países? El formato y composición de las direcciones varía mucho entre los diferentes países. Si solo está tratando con un solo país, el modelo puede ser mucho más simple que si quiere almacenar direcciones de cualquier país de forma estructurada ... – KristoferA
Francia sería perfecta ;-) Tiene razón: país único direcciones (Estados Unidos sería el más común, creo) sería un excelente punto de partida. – Mac