【问题标题】:Program design - how to improve it and how to avoid coupling (Python)?程序设计 - 如何改进它以及如何避免耦合(Python)?
【发布时间】:2015-03-23 21:56:42
【问题描述】:

在下面的 Python 程序结构中,有两个带有函数的模块。

问题描述:

  1. 函数在其他函数中使用。强耦合(依赖)。 例如,从文件读取的模块 2 中的 func1() 被多次调用,因为它在两个模块中的几乎所有其他函数中都被调用。 这是资源和性能密集型的做法,但仅此一项是不好的做法。
  2. 从文件中读取这么多次(每次调用 funct1())可能代价高昂。

问题: 改进此设计的好方法是什么?

例如,将辅助模块 2 中的函数作为参数传递给模块 1 中的函数? [如果我这样做,我仍然在模块 2 中的函数相互依赖(即 funct4() 使用 funcr1()、funct2()、funct3() 等)]

我的范例是: 我当时在想:“啊,我将有一个主模块,主要的事情发生在这里。然后我将有一个辅助模块,用于执行一些准备工作和清理工作,并从模块 1 调用它们。” (好吧,现在我有这个烂摊子。) 我想知道一个好的设计是否是让功能之间的依赖减少?每个函数只做一件事,不调用其他函数?? 我应该使用类吗?如何?是关于何时使用类还是模块?功能设计还是面向对象设计?

您将如何重新设计它以尽可能减少耦合并且文件只读取一次(或尽可能少)?

感谢任何提示。

模块 1

(主模块,程序在这里执行)

从模块 2 导入 *

f1()
- 使用 funct1() 4 次
- 使用 funct2() 2 次​​p>

f2()
- 使用 func1() 2 次
- 使用 func2() 2 次​​p>

f3()
- 使用 func1() 1 次

f4()
- 使用 func2() 3 次
- 使用 func3() 3 次
- 使用 func4() 1 次

f5()
- 使用 func1() 2 次
- 使用 func2() 2 次
- 使用 func4() 4 次

f6()
- 使用 func1() 3 次
- 使用 func2() 3 次
- 使用 func4() 2 次​​p>

模块 2

(具有为模块 1 提供清理和其他功能的辅助函数)

func1()
从文件中读取(使用 open('x.txt', 'r') af f: ...

func2()
- 使用 func1 1 次

func3()
- 使用 func1 1 次

func4()
- 使用 func1() 1 次
- 使用 func2() 2 次 - 使用 func3() 1 次

【问题讨论】:

  • 其中一些问题非常主观,如果没有更多信息,将很难回答。如果您只是一般地询问这些想法,programmers.stackexchange.com 可能是一个更好的提问地点。如果您有特定的问题,那么文件有多大?所有这些功能都需要文件的全部内容吗?文件是否有某种结构(即 csv 或 json)?你只是从文件中读取吗?程序是做什么的?
  • 它是用 Python 编写的 XML 解析器。程序读取并处理一个 XML 文件。模块 1 主要检查语法有效性。模块 2 提供了一些帮助功能,例如获取所有标签作为列表、计算尖括号、获取标签名称、tgs 之间的数据内容等。该应用程序有 2 个模块长,正如您在问题中看到的那样(模块 1 中约有 10 个函数模块 2 中大约有 6 个)。读取的 XML 文件可以是任意大小。
  • 大多数函数确实需要访问 XML 文件。我遇到的问题是,在所有这些函数中,我只是调用 get_xml_file() 方法,这意味着文件被读取了很多次。在我看来,这本身就是一个问题,我不知道如何更改它。此外,我在另一个执行其他操作的函数中使用调用 get_xml_file() 的函数,因此文件被读取两次(调用 get_xml_file()两次)不需要。一定有更好的设计……?
  • 如果您还没有,您可能希望将您的 xml 阅读器设为一个类。然后你可以将文件对象传递给构造函数(看看 pythons 的 CSV 模块)。如果文件内容适合内存,那么您可以将文件读入类成员变量。更好的方法可能是保留文件对象,并且只在任何时候读取所需的内容(使用 seek 方法移回文件的开头)。这也将允许您从其他类方法访问文件,就像 self.file 而不是调用函数。

标签: python design-patterns module


【解决方案1】:

假设文件没有被写入,我已经创建了一个非常笼统的大纲,说明一种减少文件打开和关闭次数的方法。以及调用其他函数的次数。它们应该在Helpers() 的初始化时各运行一次。虽然,这并没有真正减少耦合量,因为助手的性质。

模块2:

class Helpers(object):
    def __init__(self, fp=None):
        self.contents = self.func1(self.fp)
        self.func2_results = self.func2()
        self.func3_results = self.func3()
        self.func4_results = self.func4()
        self.results = {'name2':self.func2_results,
                        'name3':self.func3_results,
                        'name4':self.func4_results
                       }

    def func1(self):
        # read file
        with open(...) as f:
            contents = f.read()
        return contents

    def func2(self):
        # doStuff(self.contents)
        return something

    def func3(self):
        # doStuff(self.contents)
        return something

    def func4(self):
        # func2 and func3 were already run once in init
        # so lets use the results from them
        # self.func2_results
        # self.func2_results
        # self.func3_results
        return something       

模块1:

from module2 import Helpers

class Main(object):
    def __init__(self, fp=None):
        self.helper = Helpers(self.fp)
        self.contents = self.helper.contents
        self.name2 = self.helper.results['name2']
        self.name3 = self.helper.results['name3']
        self.name4 = self.helper.results['name4']
    def f1(self):
        # doStuff(self.contents)
        # doStuff(self.name2)
        return thing1
    def f2(self):
        # doStuff(self.contents)
        # doStuff(self.name2)
        return thing2
    def f3(self):
        # doStuff(self.helper.contents)
        return thing3
    def f4(self):
        # doStuff(self.name2)
        # doStuff(self.name3)
        # doStuff(self.name4)
        return thing4
    def f5(self):
        # doStuff(self.contents)
        # doStuff(self.name2)
        # doStuff(self.name4)
        return thing5
    def f6(self):
        # doStuff(self.contents)
        # doStuff(self.name2)
        # doStuff(self.name4)
        return thing6

然后它可以像这样运行:

from module1 import Main

here = Main(fp="/some/file.xml")
here2 = Main(fp="/some/file2.xml")
print(here.name2)
print(here.name3)
print(here.name4)
# each method will have only run once 
f1 = here.f1()
f2 = here.f2()
f3 = here.f3()
f4 = here.f4()
f5 = here.f5()
f6 = here.f6()
# these will run the helpers again from within `Helpers()`
# say for example if the file contents have been updated
h1 = here.helper.func1()
h2 = here.helper.func2()
h3 = here.helper.func3()
h4 = here.helper.func4()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2012-05-02
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 2015-08-05
    • 2011-06-03
    相关资源
    最近更新 更多