在创业扩大后,小明接入了许多配送合作伙伴。有骑车的、走路的、无人机的,甚至还有“宠物快递机器人”。
但每次集成新配送方式时,小明都要重复写一遍整个配送流程代码:
void deliver() {
接单();
取货();
送货();
签收();
}
不过每种快递方式中有些步骤略有不同,比如:
小明头大了:“这些流程大部分一样,只有个别步骤不同,我到底要怎么写才清晰又灵活呢?”
它定义一个算法框架,让子类去实现某些步骤,而框架本身流程固定,不让乱改。
class DroneDelivery {
public:
void deliver() {
std::cout << " 接单" << std::endl;
std::cout << " 取货" << std::endl;
std::cout << " 无人机飞行中..." << std::endl;
std::cout << " 放入指定位置,无需签收" << std::endl;
}
};
class DogDelivery {
public:
void deliver() {
std::cout << " 接单" << std::endl;
std::cout << " 取货" << std::endl;
std::cout << " 奔跑送货中..." << std::endl;
std::cout << " 喂狗粮..." << std::endl;
std::cout << "✅ 用户签收" << std::endl;
}
};
class DeliveryProcess {
public:
// 模板方法:定义配送的整体流程
void deliver() {
takeOrder();
pickup();
transport();
if (needFeed()) feedPet();
dropoff();
if (needSign()) sign();
}
virtual ~DeliveryProcess() {}
protected:
void takeOrder() {
std::cout << " 接单" << std::endl;
}
void pickup() {
std::cout << " 取货" << std::endl;
}
virtual void transport() = 0; // 抽象步骤:运输
virtual void dropoff() = 0; // 抽象步骤:放置或交货
virtual void sign() {
std::cout << "✅ 用户签收" << std::endl;
}
virtual bool needSign() { return true; } // 钩子方法
virtual bool needFeed() { return false; }
virtual void feedPet() {}
};
class DroneDelivery : public DeliveryProcess {
protected:
void transport() override {
std::cout << " 无人机飞行中..." << std::endl;
}
void dropoff() override {
std::cout << " 放入指定位置,无需签收" << std::endl;
}
bool needSign() override {
return false;
}
};
class DogDelivery : public DeliveryProcess {
protected:
void transport() override {
std::cout << " 奔跑送货中..." << std::endl;
}
void dropoff() override {
std::cout << " 狗狗等待主人签收..." << std::endl;
}
bool needFeed() override {
return true;
}
void feedPet() override {
std::cout << " 喂狗粮..." << std::endl;
}
};
int main() {
DeliveryProcess* drone = new DroneDelivery();
DeliveryProcess* dog = new DogDelivery();
std::cout << "\n 无人机配送流程:" << std::endl;
drone->deliver();
std::cout << "\n 宠物快递流程:" << std::endl;
dog->deliver();
delete drone;
delete dog;
}
无人机配送流程:
接单
取货
无人机飞行中...
放入指定位置,无需签收
宠物快递流程:
接单
取货
奔跑送货中...
喂狗粮...
狗狗等待主人签收...
✅ 用户签收
特点 | 不用模板方法 | 用模板方法 |
---|---|---|
结构 | 冗余、混乱 | 清晰、统一流程 |
灵活性 | 添加新逻辑困难 | 子类重写局部逻辑即可 |
可维护性 | 不一致、易错 | 逻辑集中、标准统一 |
“用了模板方法模式,我只需要定义一次流程,后续加狗狗、仓鼠、老鹰送货都不怕了!”