大鳥點炒飯,小菜炒麵。大鳥覺得炒麵不錯也點一份,卻發現「忘放鹽」。小菜說:好不好吃由廚師決定,心情好就是好菜,心情壞就是垃圾。大鳥反駁:麥當勞/肯德基味道穩定,因為有標準化工作流程——原料克數、加熱時間、鹽量嚴格規定,全門店必遵守。於是大鳥出題:實現畫小人程序,要求流程固化,不得缺胳膊少腿。
class PersonThinBuilder {
Graphics g;
void Build() {
g.DrawEllipse(50,20,30,30); // 頭
g.DrawRectangle(60,50,10,50); // 身
g.DrawLine(60,50,40,100); // 左臂
g.DrawLine(70,50,90,100); // 右臂
g.DrawLine(60,100,45,150); // 左腿
g.DrawLine(70,100,85,150); // 右腿
}
};
class PersonFatBuilder { ... }; // 身體換成橢圓,其餘同
問題:想加高個小人?極易漏畫部位,「忘放鹽」問題依存。
定義:將產品內部表象與生成過程分離,使同一構建過程可創建不同表象產品。強制分步驟構建,客戶端無需知曉內部細節。

class PersonBuilder {
protected: Graphics g;
public:
PersonBuilder(Graphics _g) : g(_g) {}
virtual void BuildHead() = 0;
virtual void BuildBody() = 0;
virtual void BuildArmLeft() = 0;
virtual void BuildArmRight() = 0;
virtual void BuildLegLeft() = 0;
virtual void BuildLegRight() = 0;
};
class PersonThinBuilder : public PersonBuilder {
public:
PersonThinBuilder(Graphics g) : PersonBuilder(g) {}
void BuildHead() override { g.DrawEllipse(50,20,30,30); }
void BuildBody() override { g.DrawRectangle(60,50,10,50); }
void BuildArmLeft() override { g.DrawLine(60,50,40,100); }
void BuildArmRight() override { g.DrawLine(70,50,90,100); }
void BuildLegLeft() override { g.DrawLine(60,100,45,150); }
void BuildLegRight() override { g.DrawLine(70,100,85,150); }
};
// PersonFatBuilder、PersonTallBuilder 同理實現各步驟
新增小人類型只需繼承 PersonBuilder 實現 6 個步驟,編譯器強制檢查,絕不會漏畫任何部位。構建流程固化,表象靈活變化——完美解決「炒麵忘放鹽」問題。