"如何从核心功能中提取第三方实现细节?"

2024-04-26 20:28:39 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是一个问题和需求的例子。你知道吗

场景:我们有一个Web应用程序,控制器有一个功能,可以将HTML转换为PDF。我们必须根据需要和技术的进步,换用各种发动机。这意味着我们需要不断更改核心文件。它甚至可以是一个执行我的工作而不是在本地实现的web服务。你知道吗

总体而言,伪Python的当前体系结构是:

控制器

def requestEntry():
    """Entry point"""
    html = REQUEST['html'] , css = REQUEST['css']
    createPDF(html,css)

def createPDF(html,css):
    """Sigh"""
    #Hardcoding Begines
    configured_engine  = getXMLOption('configured_engine')
    if configured_engine == "SuperPDFGen":
       #Returns SuperGen's PDF Blob
       supergen = SuperGen(html,css)
       return supergen.pdfout() 
    if configured_engine = "PISA":
       pisa = PISA(html,css)
       return pisa.pdf_out()

这里的问题是每一个新的引擎需求都是控制器中的代码更改。假设我们找到一种新技术,我们就必须升级核心软件版本。

解决:

我能想到的一种方法是定义这样一个简单的类:

def createPdf(data,engine):
    pdf_render = PDFRender(html,css,engine)
    return pdf_render.pdf_out() 

所以现在我们将PDFRender排除在外,核心版本不需要再为实现更改而更改,但是我们需要在PDFRender类中使用If梯形图对引擎进行编码。你知道吗

为了扩展这个想法,我可以用一个约定引擎作为模块名。但如果将其作为引擎给定,则它不能适应URL。你知道吗

def createPdf(data,engine):
    #Convert the string called engine to a Module ! Sigh 
    import engine Engine!!
    pdf_render = engine.Engine(data)
    return pdf_render()

是否有任何建议的范例或插件适配器机制?它应该使用URL或Python模块作为输入,并完成任务。新的实现应该是独立的,并且可以插入到现有的代码中,核心特性中没有版本更改。我该怎么做?我认为核心应该从服务(python模块、子进程或url)的角度来讨论这就是我想要实现的。你知道吗


Tags: 模块引擎版本核心datareturnpdfdef
2条回答

添加一个包,在其中粘贴渲染器,每个模块对应一个Python模块,模块以“engine”命名,渲染器类以“PDFRenderer”命名。然后在包的__init__中扫描目录中的模块,从每个模块导入PDFRenderer类,并构建一个nginename:PDFRenderer映射,并使用它获取引擎的PDFRenderer类。你知道吗

现在看来,每次更改pdf呈现器时,都必须更改几行代码。代码简单易懂。你知道吗

当然,您可以将其全部抽象出来,使用配置文件,并添加插件体系结构。但你会得到什么?而不是更改几行代码,而是更改一个插件或一个配置文件,这台机器将需要维护:例如,如果您决定需要将一些标志传递给其中一个呈现器,那么您必须将该功能添加到配置文件或您选择的任何抽象。你知道吗

你认为你会改变多少次?我猜最多一年一次。保持代码简单,在真正需要之前不要构建复杂的解决方案。你知道吗

相关问题 更多 >