Nous avons une application Web qui prend des entrées utilisateur ou des recherches de base de données pour former des opérations sur certaines ressources physiques. La conception peut être simplement présenté comme schéma suivant:Aide au refactoring de code - comment réorganiser les validations
entrée utilisateur < => modèle objet < => stockage base de données
validations sont nécessaires à la demande provenant de l'entrée d'utilisateur, mais pas quand on vient de visites de consultation de base de données (car si un enregistrement existe, ces attributs doivent déjà avoir été validés auparavant). J'essaye de refactoriser le code de sorte que les validations se produisent dans le constructeur d'objet au lieu de l'ancienne (quelques routines séparées de validation)
Comment décideriez-vous quelle est la meilleure façon? (La différence fondamentale de la méthode 1 (ancienne) et 2 est que les validations dans 1 ne sont pas obligatoires et découplées de l'instanciation d'objet mais 2 les lie et les rend obligatoires pour toutes les requêtes)
Voici deux exemples d'extraits de code pour Design 1 et 2:
Méthode 1:
# For processing single request.
# Steps: 1. Validate all incoming data. 2. instantiate the object.
ValidateAttribures(request) # raise Exceptions if failed
resource = Resource(**request)
Méthode 2:
# Have to extract out this since it does not have anything to do with
# the object.
# raise Exceptions if some required params missing.
# steps: 1. Check whether its a batching request. 2. instantiate the object.
# (validations are performed inside the constructor)
CheckIfBatchRequest(request)
resource = Resource(**request) # raise Exceptions when validations failed
Dans une demande de traitement par lots: Méthode 1:
# steps: 1. validate each request and return error to the client if any found.
# 2. perform the object instantiate and creation process. Exceptions are
# captured.
# 3. when all finished, email out any errors.
for request in batch_requests:
try:
ValidateAttribute(request)
except SomeException, e:
return ErrorPage(e)
errors = []
for request in batch_requests:
try:
CreatResource(Resource(**request), request)
except CreationError, e:
errors.append('failed to create with error: %s', e)
email(errors)
Méthode 2:
# steps: 1. validate batch job related data from the request.
# 2. If success, create objects for each request and do the validations.
# 3. If exception, return error found, otherwise,
# return a list of pairs with (object, request)
# 4. Do the creation process and email out any errors if encountered.
CheckIfBatchRequest(request)
request_objects = []
for request in batch_requests:
try:
resource = Resource(**request)
except SomeException, e:
return ErrorPage(e)
request_objects.append((resource, request))
email(CreateResource(request_objects)) # the CreateResource will also need to be refactored.
Avantages et inconvénients que je peux voir ici sont:
- Méthode 1 suit plus proche de la logique métier. Aucune validation redondante ne vérifie quand les objets proviennent de la recherche db. Les routines de validation sont mieux maintenables et lues.
- La méthode 2 rend facile et propre pour l'appelant. Les validations sont obligatoires même si elles proviennent de la recherche db. Les validations sont moins maintenables et lues.
Je vous suggère de raccourcir votre question, résumer et reformater le code (le l'éditeur incorporé a un bouton "code"). –
Vous devriez certainement raccourcir la question. Aussi est-ce vraiment un projet django. Si c'est le cas, vous devriez expliquer pourquoi la validation n'est pas implémentée sur les formulaires (comme le fait Django). – muhuk
C'est. A l'origine le développeur n'utilisait pas de formulaires mais de Context avec des données, des formulaires construits du coté client. Quand je l'ai pris, ce design n'a pas été changé. –