สมมติว่าผมมีลำดับชั้นของชั้นเรียน:Item
Rectangle, Circle, Triangle
ฉันต้องการที่จะสามารถวาดพวกเขาดังนั้นความเป็นไปได้ครั้งแรกของฉันคือการเพิ่มDraw()
วิธีเสมือนในแต่ละ:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
อย่างไรก็ตามฉันต้องการแยกฟังก์ชั่นการวาดภาพเป็นห้องสมุดวาดแยกในขณะที่ห้องสมุด Core มีเพียงการแสดงขั้นพื้นฐาน มีความเป็นไปได้สองอย่างที่ฉันคิดได้:
1 - A DrawManager
ที่รับรายการItem
s และต้องใช้dynamic_cast<>
เพื่อระบุสิ่งที่ต้องทำ:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
สิ่งนี้ไม่เหมาะเนื่องจากอาศัย RTTI และบังคับให้คลาสหนึ่งต้องระวังรายการทั้งหมดในลำดับชั้น
2 - วิธีอื่นคือการเลื่อนความรับผิดชอบไปยังItemDrawer
ลำดับชั้น ( RectangleDrawer
ฯลฯ ):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
สิ่งนี้ทำให้การแยกข้อกังวลระหว่างการแสดงพื้นฐานของรายการและรหัสสำหรับการวาดภาพ แม้ว่าปัญหาคือคลาสไอเท็มขึ้นอยู่กับคลาสรูปวาด
ฉันจะแยกรหัสรูปวาดนี้ออกเป็นห้องสมุดแยกได้อย่างไร วิธีแก้ปัญหาสำหรับรายการที่จะส่งคืนคลาสโรงงานของคำอธิบายบางอย่างหรือไม่? อย่างไรก็ตามสามารถกำหนดสิ่งนี้ได้อย่างไรเพื่อให้ไลบรารี Core ไม่ได้ขึ้นอยู่กับไลบรารี Draw