ฉันขอสนับสนุนกลยุทธ์ที่ระบุไว้ในคำตอบของ @DocBrown@DocBrown
ฉันจะแนะนำการปรับปรุงคำตอบ
การโทรออก
myMap.Add(1,new Strategy1());
myMap.Add(2,new Strategy2());
myMap.Add(3,new Strategy3());
สามารถกระจาย คุณไม่จำเป็นต้องกลับไปที่ไฟล์เดียวกันเพื่อเพิ่มกลยุทธ์อื่นซึ่งปฏิบัติตามหลักการ Open-Closed ที่ดียิ่งขึ้น
สมมติว่าคุณใช้งานStrategy1
ในไฟล์ Strategy1.cpp คุณสามารถมีบล็อคของรหัสต่อไปนี้ได้
namespace Strategy1_Impl
{
struct Initializer
{
Initializer()
{
getMap().Add(1, new Strategy1());
}
};
}
using namespace Strategy1_Impl;
static Initializer initializer;
คุณสามารถทำซ้ำรหัสเดียวกันในทุกไฟล์ StategyN.cpp อย่างที่คุณเห็นนั่นจะเป็นรหัสซ้ำหลายครั้ง เพื่อลดความซ้ำซ้อนของรหัสคุณสามารถใช้เทมเพลตที่สามารถใส่ในไฟล์ที่ทุกStrategy
คลาสสามารถเข้าถึงได้
namespace StrategyHelper
{
template <int N, typename StrategyType> struct Initializer
{
Initializer()
{
getMap().Add(N, new StrategyType());
}
};
}
หลังจากนั้นสิ่งเดียวที่คุณต้องใช้ใน Strategy1.cpp คือ:
static StrategyHelper::Initializer<1, Strategy1> initializer;
บรรทัดที่เกี่ยวข้องใน StrategyN.cpp คือ:
static StrategyHelper::Initializer<N, StrategyN> initializer;
คุณสามารถใช้เทมเพลตไปอีกระดับโดยใช้เทมเพลตชั้นเรียนสำหรับชั้นเรียนกลยุทธ์ที่เป็นรูปธรรม
class Strategy { ... };
template <int N> class ConcreteStrategy;
และจากนั้นแทนการใช้Strategy1
ConcreteStrategy<1>
template <> class ConcreteStrategy<1> : public Strategy { ... };
เปลี่ยนคลาสตัวช่วยเพื่อลงทะเบียนStrategy
s เป็น:
namespace StrategyHelper
{
template <int N> struct Initializer
{
Initializer()
{
getMap().Add(N, new ConcreteStrategy<N>());
}
};
}
เปลี่ยนรหัสใน Strateg1.cpp เป็น:
static StrategyHelper::Initializer<1> initializer;
เปลี่ยนรหัสใน StrategN.cpp เป็น:
static StrategyHelper::Initializer<N> initializer;