模板方法模式的UML类图入下 :
解决的问题 :
- 一些方法通用,但子类重写了很多次
- 优雅的复用代码
详细描述:
- 通用的方法抽出来到父类实现,特殊的行为在子类重写
注意点:
- 模板方法通常会加 final
例子:
- 发生告警时,不同的告警(如
摄像头告警
和车辆告警
)有相同的方法,如生成告警记录,告警等级提升,关闭告警等都一样,于是可以提升到父类实现。 - Java中用了很多
-
AbstractList
的addAll()
方法 -
InputStream
的read(byte b[], int off, int len)
方法 -
servlet
也是,service()
方法是模板方法,子类重写doGet
和doPost
-
comparable
也是,提供了固定的comparaTo()
给子类重写
-
- 个人理解:
abstractClass
应该都是模板方法模式
代码:
-
父类模板要 抽取公共代码,final修饰
#ifndef _ALERTTEMPLATE_H #define _ALERTTEMPLATE_H #include "../MajiaoObject.hpp" // 抽象告警类 class AlertTemplate : public MajiaoObject { public : GET_SET(public, string, alertMsg); GET_SET(public, string, alertTime); GET_SET(public, int, alertLevel); GET_SET(public, int, status); AlertTemplate() { } AlertTemplate(string msg, string time, int level) : alertMsg(msg), alertTime(time), alertLevel(level) { } ~AlertTemplate() { } // 需要子类重写的模板 virtual void buildAlert() = 0; virtual void sendAlert() = 0; virtual void callLeaders() = 0; virtual void closeAlert() = 0; // 父类把不变的东西定死 virtual void alertHappend() final { this->buildAlert(); this->sendAlert(); this->callLeaders(); this->closeAlert(); } }; #endif // _IALERTTEMPLATE_H
-
- 实现类A
CarAlert
重写父类方法,但是不需要改动父类抽取好的方法alertHappend()
#ifndef _CARALERT_H #define _CARALERT_H #include "../AlertTemplate.hpp" class CarAlert : public AlertTemplate { public : GET_SET(public, int, loadLimit); GET_SET(public, double, v); GET_SET(public, int, loadNum); GET_SET(public, int64_t, driverId); GET_SET(public, string, carNumber); CarAlert() { } CarAlert(string carNum) : carNumber(carNum) { } ~CarAlert() { } // 以下为重写父类的函数 virtual void buildAlert() override { this->alertMsg = "车辆【" + carNumber + "】当前人数为"; this->alertMsg += loadNum + " 人 "; } virtual void sendAlert() override { } virtual void callLeaders() override { callDriver(); } virtual void closeAlert() override { if (this->loadNum < 10) { this->setstatus(0); } } // alertHappend()被抽取到父类里了 private : void callDriver() { cout << "通知司机" << driverId << "当前车上人数" << endl; } }; #endif // _CARALERT_H
- 实现类B
CameraAlert
,也一样
#ifndef _CAMERAALERT_H #define _CAMERAALERT_H #include "../AlertTemplate.hpp" class CameraAlert : public AlertTemplate { public : GET_SET(public, string, cameraName); CameraAlert() { } CameraAlert(string camName) : cameraName(camName) { } ~CameraAlert() { } virtual void buildAlert() { this->alertMsg = "摄像头" + cameraName + "检测到可以人员进入"; } virtual void sendAlert() { } virtual void callLeaders() { callAdmin(); } virtual void closeAlert() { } // alertHappend()被抽取到父类里了 private : void callAdmin() { cout << "尝试通知管理员" << endl; } }; #endif // _CAMERAALERT_H
- 实现类A
-
在调用方
main
里,就是普通的使用类即可AlertTemplate* alert = new CameraAlert("供电所前门摄像头"); alert->alertHappend(); // 调用父类抽取的函数 alert = new CarAlert("桂R8766"); alert->alertHappend(); // 调用父类抽取的函数