用于程序重构的 OOP 设计模式

OOP design pattern for program refactoring

我的问题是根据面向对象的编程原则重构程序。程序在一个 while 循环中 运行 无限循环,所有操作都在这个主 while 循环中。这个主循环有一个 switch-case 语句。 它有 11 个案例,所有案例都是代表语句,如 unplanned_stopplanned_stopread_data_from_xread_data_from_y... 此外,这些状态中有 if-else 子句来调用不同的功能。每个状态根据if-else决定指向下一步的另一个状态。

我已经搜索过,State Design Pattern 似乎适合这个解决方案,但我不确定。 主循环是这样的:

while(programIsRunnning)
{
   switch(programState)
   {
      case state.StartOfLoop:
          if(..) doSomething();
          else doAnotherThing();
          programState = state.PlannedStop;
          break;
      case state.PlannedStop:
          if(..) programState = state.ReadDataFromX;
          else programState = state.ReadDataFromY;
      case state.ReadDataFromX:
          if(..) programState = state.UnplannedStop;
          else programState = state.StartOfLoop;
      .
      .
      .
  

我希望我能解释清楚。这种设计很讨厌,很难理解在哪里实施新规范。对于程序的每个新请求,我都必须编辑其他状态和 if-else 子句。我是一名大三学生,我能想到的就是用 OOP 设计模式重新编码。欢迎提出任何建议。

您的任务非常适合使用 State pattern,下面我展示了 class 依赖项的示例代码。我们把大开关拆分成几个class,每个负责处理一个状态,可以把程序转移到其他状态。

比如我使用了Python语言,因为比较形象,画了几个class类似我曾经解决过的问题,我也显式添加了调用的方法对于切换到它和离开它的状态,有时这很有用。


class StateInterface:
    def on_enter(self):
        ...

    def work(self):
        ...

    def on_leave(self):
        ...


class StateOne(StateInterface):
    def __init__(self, main_program):
        self.main_program = main_program

    def on_enter(self):
        # do some init
        ...

    def work(self):
        # do some work
        new_state = StateTwo(self.main_program)
        self.main_program.change_state(new_state)

    def on_leave(self):
        # do some clear
        ...


class StateTwo(StateInterface):
    ...


class MainProgram:
    def __init__(self, initial_state: StateInterface):
        self.current_state = initial_state

    def infinite_loop(self):
        while not self.stopped:
            self.current_state.work()

    def change_state(self, new_state: StateInterface):
        self.current_state.on_leave()
        self.current_state = new_state
        self.current_state.on_enter()