Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在一个简单接口后面转换和组合多种数据类型的模式_Python_Django_Design Patterns_Abstraction - Fatal编程技术网

Python 在一个简单接口后面转换和组合多种数据类型的模式

Python 在一个简单接口后面转换和组合多种数据类型的模式,python,django,design-patterns,abstraction,Python,Django,Design Patterns,Abstraction,我很难为一个小事件日志框架概念化一个合理的抽象,也没有遇到任何可以在野外应用的类似的东西 概述:我们的web应用程序需要从服务器端记录事件。事件数据通过json编码写入平面文件。事件可能是页面视图、注册、错误条件等 所有事件都将包含一组核心数据,如web请求信息和会话状态。任何事件都应该能够定义要记录的附加数据 理想情况下,触发事件的接口将非常小。事件定义和数据要求应在单个配置文件中定义。数据验证和数据转换应该隐藏在此配置文件后面。换句话说,记录事件的接口应该只需要事件名称以及要在事件中转换和记

我很难为一个小事件日志框架概念化一个合理的抽象,也没有遇到任何可以在野外应用的类似的东西

概述:我们的web应用程序需要从服务器端记录事件。事件数据通过json编码写入平面文件。事件可能是页面视图、注册、错误条件等

所有事件都将包含一组核心数据,如web请求信息和会话状态。任何事件都应该能够定义要记录的附加数据

理想情况下,触发事件的接口将非常小。事件定义和数据要求应在单个配置文件中定义。数据验证和数据转换应该隐藏在此配置文件后面。换句话说,记录事件的接口应该只需要事件名称以及要在事件中转换和记录的数据结构

我最初的想法是将单个数据结构映射到单个函数,该函数的职责是将数据结构转换为字典,最终将字典合并到最终的事件对象中,然后对json进行编码并写入文件。我把它们称为“composer”函数。在Django术语中,配置文件中的某些内容将映射到一个“request\u composer”函数,例如,传递给视图的HTTP请求对象。该函数将构造一个从该请求对象中提取的数据字典。从视图发出的事件需要传入该“请求”对象


我想我的问题是,我是否忽略了一种模式或抽象,它可以干净地转换任意数据结构,并将它们合并到最终的数据结构中。我觉得这种“单一数据类型映射到单一转换函数”有点笨拙和不雅观。当单个转换器接受多个参数时,它也会发生故障。

这听起来很像Facade(复杂实现的简单接口),可能与策略(在运行时或配置/启动期间在流程的几个具体实现之间切换)和Builder相结合(提供一个复杂对象的通用抽象描述,几个不同的策略可以转换为实际的表示)。您可能会发现,一旦使用了策略,就不需要使用Facade

所以更具体一点:

Facade将有两种方法:Log和SetLogger

如果使用Prototype,则事件的类型和事件的每个组件的类型都将相同。只有在需要记录非常复杂的事件或需要以几种非常不同的方式记录事件时,才会使用Prototype

将有一个用于记录器(策略)的接口。这在SetLogger方法的Facade中使用。如果您使用Prototype,Facade.Log和Logger.Log的接口可能都有类似Log(PrototypeEvent e)的方法

下面的链接是一个简单的记录器,它不使用原型,但使用策略。这里没有门面,因为前端类实际上只跟踪当前记录器


这里没有硬性规定。我的建议是,如果您有完整的设计,并且希望从一个视图触发一个事件,那么您应该开始想象实现的样子

因此,我的建议有以下几个具体目标:

  • 必须明确引用事件(Django的设计)
  • 事件可以重用或特定于应用程序
  • 每个事件都需要一个请求实例
  • 每个事件都可以收集额外的任意参数或关键字参数,它们所要做的就是为事件处理器提供上下文
  • 事件处理器将提取请求数据,将其与上下文序列化为JSON,并将其附加到日志文件中
假设您在项目中的
myproj.events
创建应用程序,并且在
myproj.myapp
中有一些应用程序

让我们在
myproj/events/\uuuuuu init\uuuuuuuuu.py
创建事件处理器和默认的项目范围实例:

import 

class Events(object): pass  # Use your imagination

events = Events(logfile=StringIO.StringIO)  # Say I wanted to log to a file-like object
myproj/myapp/events.py
中,您可以在单个模块中配置所有
myproj.myapp
app特定事件:

from myproj.events import events

@events.register_event
def view_requested(request)
    return request


@events.register_event
def user_signed_in(request)
    user = request.user
    return request, dict(username=user.username, gravatar=user.profile.gravatar)
然后在您的视图中,您可以:

from django.http import HttpResponse
from myproj.myapps import events


def foo(request):
    events.view_requested(request)
    return HttpResponse
这种方法采用了大量的设计提示,它提供了一个直观的界面,通过简单地调用发生的上下文中的相关信号,重用接收器回调中隔离的行为


事实上,我甚至建议您查看一下它的实现,看看是否可以根据您的特定需求实际使用或扩展它。

好主意。谢谢您的深入回答