راه حل پيشنهادي من اينه. فرض کنيد P کلاس پايه باشه و C1 و C2 کلاسهاي مشتق شده.
براي کلاس P يک تابع مجازي با prototype زير تعريف ميکنيم:
virtual P* createP( Map<ArgumentName, ArgumentValue> & arguments );
و همچنين يک تابع مجازي static که در واقع ميخواد وظايف تابع سازنده (constructor) کلاس P رو به عهده بگيره. اسم اين تابع رو ميتونيم بذاريم initializer (يا staticConstructor):
static P* initializer( P* p, Map<ArgumentName, ArgumentValue>& arguments);
اين تابع چون constructor يا destructor نيست ميتونه توابع مجازي P رو صدا بزنه و به اين ترتيب چند ريختي (polymorphism) در سازنده امکانپذير ميشه!
و اما در کلاسهاي فرزند، مثلا C1، تابع createP رو به سادگي به شکل زير تعريف ميکنيم:
virtual P* createP( Map<ArgumentName, ArgumentValue> & arguments )
{
return new C1( ... ); // extract constructor arguments from the map and call the constructor
}
و تابع سازنده کلاس فرزند هم بعد از مقداردهي هاي اوليه خودش، staticConstructor کلاس P رو صدا ميزنه:
C1( ... )
{
...
// put the constructor arguments into the map and call the parent's static constructor
P::initializer( this, arguments );
}
به دليل ضيق وقت خلاصه نوشتم. اگه جاييش مبهم بود بگيد تا بيشتر توضيح بدم.
قسمتي از ايده اين راه حل رو از الگوي Factory گرفتم و در عمل کار ميکنه و ظاهرا به اصول شيء گرايي پايبنده! عقل من در همين حد ميرسه. اما مشتاقم يکي راهنمايي کنه. ميخوام بدونم راه حلم چه ايرادي داره و الگوي طراحي استاندارد براي وضعيتي که توصيف کردم - اگه وجود داره - چيه.
متشکرم. مقاله رو اجمالا خوندم. ظاهرا فقط به مشکل اشاره کرده و راهنمايي يا راه حلي ارائه نداده؟! |