You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python场景下基于Builder设计模式扩展Updater模式实现高效对象更新的方案问询

Extending the Builder Pattern for Safe, Maintainable Object Updates

Great question—you’re absolutely on the right track thinking about extending the Builder pattern here. Let’s walk through a clean Python implementation that checks all your boxes: no broken encapsulation, delegated update logic, and scalability as your class grows.

Core Idea

We’ll create an Updater class (parallel to your original Builder) that:

  1. Starts with the current state of an existing A object
  2. Lets you chain updates to individual fields (just like the Builder)
  3. Runs your full validation logic before applying changes
  4. Safely updates the original object without exposing public setters

Implementation Code

First, we’ll keep class A encapsulated—no public setters, only read-only properties and a protected method to update state (only accessible to our Updater):

class A:
    def __init__(self, m1, m2):
        # Internal state remains private
        self._m1 = m1
        self._m2 = m2

    # Read-only properties for external access
    @property
    def m1(self):
        return self._m1

    @property
    def m2(self):
        return self._m2

    # Protected method: only trusted classes (like our Updater) should call this
    def _update_state(self, **kwargs):
        # Safely update only valid internal fields
        for field, value in kwargs.items():
            internal_field = f"_{field}"
            if hasattr(self, internal_field):
                setattr(self, internal_field, value)
            else:
                raise ValueError(f"Invalid field for update: {field}")

Next, the AUpdater class—reusing the Builder’s familiar API but tailored to updating existing objects:

class AUpdater:
    def __init__(self, existing_a: A):
        # Initialize with the current state of the object
        self._current_state = {
            "m1": existing_a.m1,
            "m2": existing_a.m2
        }
        self._target_object = existing_a

    # Chainable setters for each field
    def set_m1(self, m1):
        self._current_state["m1"] = m1
        return self

    def set_m2(self, m2):
        self._current_state["m2"] = m2
        return self

    # Reusable validation logic (same as your Builder's _validate)
    def _validate(self):
        m1, m2 = self._current_state["m1"], self._current_state["m2"]
        assert m1 < 1000, "m1 must be less than 1000"
        assert m1 < m2, "m1 must be less than m2"

    # Apply validated changes to the original object
    def apply(self):
        self._validate()
        self._target_object._update_state(**self._current_state)
        return self._target_object

Bonus: Reuse Builder Logic for DRY Code

If you want to share setter and validation logic between your original Builder and the new Updater, extract that into a base class:

class ABasicConfigurer:
    def __init__(self):
        self._state = {}

    def set_m1(self, m1):
        self._state["m1"] = m1
        return self

    def set_m2(self, m2):
        self._state["m2"] = m2
        return self

    def _validate(self):
        m1, m2 = self._state["m1"], self._state["m2"]
        assert m1 < 1000, "m1 must be less than 1000"
        assert m1 < m2, "m1 must be less than m2"

# Original Builder, now using the base class
class ABuilder(ABasicConfigurer):
    def build(self):
        self._validate()
        return A(**self._state)

# Updater, reusing the same base logic
class AUpdater(ABasicConfigurer):
    def __init__(self, existing_a: A):
        super().__init__()
        self._state = {
            "m1": existing_a.m1,
            "m2": existing_a.m2
        }
        self._target_object = existing_a

    def apply(self):
        self._validate()
        self._target_object._update_state(**self._state)
        return self._target_object

Why This Works for Your Requirements

  1. No Broken Encapsulation:

    • Class A has no public setters—external code can only modify state through the AUpdater.
    • The _update_state method is protected (by Python’s naming convention), so only trusted code (like our Updater) can use it.
  2. Delegated Update Responsibility:

    • All validation and update orchestration lives in AUpdater, not in A itself. Class A stays focused on its core responsibilities, not update logic.
  3. Maintainable as Complexity Grows:

    • Adding a new field only requires:
      1. Adding it to A’s __init__
      2. Adding a set_xxx method to the base ABasicConfigurer
      3. Updating the validation logic once
    • No need to write dozens of combination update methods or a giant "god method"—users can chain any combination of setters they need.

Example Usage

# Create an initial object with Builder
a = ABuilder().set_m1(500).set_m2(600).build()
print(a.m1, a.m2)  # Output: 500 600

# Update it with Updater
updated_a = AUpdater(a).set_m1(700).set_m2(800).apply()
print(updated_a.m1, updated_a.m2)  # Output: 700 800

# Invalid update will fail validation before changing anything
try:
    AUpdater(a).set_m1(1500).apply()
except AssertionError as e:
    print(e)  # Output: m1 must be less than 1000

内容的提问来源于stack exchange,提问作者Gulzar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:37:33