在Python中使用策略设计模式

时间:2018-11-08 00:04:19

标签: python strategy-pattern

我在一个有多个项目的地方工作。根据项目,我希望以某种方式处理列表中的项目。我认为这个问题很适合战略模式。但是,在完全致力于此模式之前,我创建了一个小应用程序来演示我认为最终应用程序将如何工作。

首先,我创建了一个策略类:

std::pair

如您所见,我定义了一些方法,这些方法会导致do_that和do_this方法在名为x的项目中以某种方式运行。

import types
import rules.work_on_x

class WorkOnProjectsStrategy:

    def __init__(self, project="default"):
        self.project = project
        self.msg = "{0} is the project.".format(self.project)

        if project == "x":
            self.do_that = types.MethodType(rules.work_on_x.do_that, self)
            self.do_this = types.MethodType(rules.work_on_x.do_this, self)

    def do_that(self):
        print("Do that!")

    def do_this(self):
        print("Do this!")

然后我创建了将利用策略类的客户端(一个简单的GUI)。

def do_that(self, thing):
    print(self.msg)
    print("Doing that on {0}".format(thing))

def do_this(self, some_thing):
    print(self.msg)
    print("Doing this on {0}".format(some_thing))

可以改进这种设计吗?我注意到一个问题是,我可能会在Strategy类中得到一个很大的if / else语句。这可能很容易理解,但是我不确定它是否特别优雅。该代码确实有效。这是在GUI中输入“ x”后的输出:

import os
import sys

from work_on_projects_strategy import WorkOnProjectsStrategy

from PySide2 import QtCore
from PySide2 import QtUiTools
from PySide2 import QtWidgets

class Client(QtWidgets.QWidget):

    def __init__(self, ui_file, parent=None):
        super().__init__(parent)

        # Load the ui file
        ui_file = QtCore.QFile(ui_file)
        ui_file.open(QtCore.QFile.ReadOnly)
        loader = QtUiTools.QUiLoader()
        self.my_widget = loader.load(ui_file)
        ui_file.close()
        self.my_widget.show()

        # Set up connections
        self.line_edit_input_asset = \
            self.my_widget.findChild(QtCore.QObject, "lineEdit_inputasset")
        self.push_button_execute = \
            self.my_widget.findChild(QtCore.QObject, "pushButton_execute")
        self.push_button_execute.clicked.connect(self.doing_stuff)

    def doing_stuff(self):
        proj = self.line_edit_input_asset.displayText()
        things = ["thing_1", "thing_2"]
        for thing in things:
            strategy = WorkOnProjectsStrategy(proj)
            if thing == "thing_1":
                strategy.do_that(thing)
            elif thing == "thing_2":
                strategy.do_this(thing)

def main():
    app = QtWidgets.QApplication()
    client_ui = os.path.join("ui", "demo_client.ui")
    client_tool = Client(client_ui)
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

我对此工作感到惊讶。

(MY_ENV) > python .\client.py
x is the project.
Doing that on thing_1
x is the project.
Doing this on thing_2

我认为您只能将一个方法动态分配给一个类的一个实例。

0 个答案:

没有答案