【发布时间】:2010-09-27 21:51:32
【问题描述】:
我们有一个 Web 应用程序,它接受用户输入或数据库查找来对某些物理资源进行一些操作。设计可以简单地用下图表示:
用户输入模型对象数据库存储
来自用户输入的请求需要验证,但来自数据库查找命中的请求不需要验证(因为如果存在记录,这些属性之前必须已经验证过)。我正在尝试重构代码,以便验证发生在对象构造函数中,而不是旧的方式(单独的几个验证例程)
您将如何决定哪种方式更好? (方法 1(旧方法)和 2 的根本区别在于 1 中的验证不是强制性的,并且与对象实例化解耦,但 2 绑定它们并使它们对所有请求都是强制性的)
以下是设计 1 和 2 的两个示例代码 sn-ps:
方法一:
# For processing single request.
# Steps: 1. Validate all incoming data. 2. instantiate the object.
ValidateAttribures(request) # raise Exceptions if failed
resource = Resource(**request)
方法二:
# 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
在批处理请求中: 方法一:
# 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)
方法二:
# 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.
我在这里看到的优点和缺点是:
- 方法 1 更接近业务逻辑。当对象来自数据库查找时,没有多余的验证检查。验证例程更易于维护和阅读。
- 方法 2 使调用者变得简单而干净。即使来自数据库查找,验证也是强制性的。验证的可维护性和可读性较差。
【问题讨论】:
-
我建议你缩短你的问题,总结并重新格式化代码(嵌入式编辑器有“代码”标签按钮)。
-
你绝对应该缩短这个问题。这也真的是一个 django 项目。如果是,你应该解释为什么没有在表单上实现验证(就像 Django 方式一样)。
-
是的。最初开发人员没有使用表单,而是使用带有数据的上下文,即在客户端构建的表单。我拿的时候这个设计没变。
-
是的,这个问题太不清楚了,无法回答。上面的代码 sn-ps 脱离了上下文,引用了未解释的名称、方法和对象。我什至无法弄清楚你想做什么。
-
这段代码有点java的味道
标签: python django optimization refactoring web-applications