“更新器”设计模式,而不是“构建器”

问题描述

这实际上与语言无关,但我总是更喜欢 Python。


The builder design pattern 用于在创建对象之前通过创建过程的委托来验证配置是否有效。

一些需要澄清的代码:

class A():
    def __init__(self,m1,m2):  # obviously more complex in life
        self._m1 = m1
        self._m2 = m2

class ABuilder():
    def __init__():
        self._m1 = None
        self._m2 = None

    def set_m1(self,m1):
        self._m1 = m1
        return self

    def set_m2(self,m1):
        self._m2 = m2
        return self

    def _validate(self):
        # complicated validations
        assert self._m1 < 1000
        assert self._m1 < self._m2

    def build(self):
        self._validate()
        return A(self._m1,self._m2)

我的问题是类似的,有一个额外的限制,由于性能限制,我不能每次都重新创建对象。
相反,我只想更新现有对象。


我想出的糟糕解决方案:

我可以做 as suggested here 并像这样使用 setter

class A():
    ...

    set_m1(self,m1):
        self._m1 = m1

    # and so on

但这很糟糕,因为使用了 setter

  1. 超越封装的目的
  2. 违背了构建器(现在是更新器)的目的,它应该验证创建后是否保留了一些复杂的配置,或者在这种情况下进行更新。

正如我之前提到的,我不能每次都重新创建对象,因为这很昂贵,而且我只想更新一些字段或子字段,并且仍然验证或子验证。


我可以向 A 添加更新和验证方法并调用它们,但这违背了委派更新责任的目的,并且在字段数量上难以处理。

class A():
   ...

   def update1(m1):
      pass # complex_logic1

   def update2(m2):
      pass # complex_logic2

   def update12(m1,m2):
      pass # complex_logic12

我可以在带有可选参数的方法中强制更新 A 中的每个字段

class A():
   ...

   def update("""list of all fields of A"""):
      pass

这又是一个难以驾驭的方法,因为这种方法由于可能有多种组合,很快就会成为神法。

强制方法始终接受 A 中的更改,并在 Updater 中进行验证也不起作用,因为 Updater 将需要查看 A' s 内部状态进行决策,导致循环依赖。


如何委派更新对象中的字段 A

以某种方式

  1. 不会破坏 A 的封装
  2. 实际上将更新的责任委托给另一个对象
  3. 易于处理,因为 A 变得更加复杂

我觉得我缺少一些将构建扩展到更新的微不足道的东西。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)