ฉันต้องออกแบบลำดับชั้นของชั้นเรียนสำหรับโครงการ C # ของฉัน โดยพื้นฐานแล้วฟังก์ชันของคลาสนั้นคล้ายกับคลาสของ WinForms ดังนั้นให้ลองใช้ชุดเครื่องมือ WinForms เป็นตัวอย่าง (อย่างไรก็ตามฉันไม่สามารถใช้ WinForms หรือ WPF ได้)
มีคุณสมบัติและฟังก์ชั่นหลักบางอย่างที่ทุกชั้นต้องการ ขนาดตำแหน่งสีการมองเห็น (จริง / เท็จ) วิธีการวาด ฯลฯ
ฉันต้องการคำแนะนำด้านการออกแบบฉันใช้การออกแบบที่มีคลาสเบสและอินเทอร์เฟซที่เป็นนามธรรมซึ่งไม่ใช่ประเภทจริง ๆ แต่ชอบพฤติกรรมมากกว่า นี่เป็นการออกแบบที่ดีหรือไม่? ถ้าไม่สิ่งที่จะเป็นการออกแบบที่ดีกว่า
รหัสมีลักษณะดังนี้:
abstract class Control
{
public int Width { get; set; }
public int Height { get; set; }
public int BackColor { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int BorderWidth { get; set; }
public int BorderColor { get; set; }
public bool Visible { get; set; }
public Rectangle ClipRectange { get; protected set; }
abstract public void Draw();
}
การควบคุมบางอย่างสามารถมีการควบคุมอื่น ๆ บางอย่างสามารถมี (เป็นเด็ก ๆ ) ดังนั้นฉันจึงคิดที่จะสร้างสองอินเตอร์เฟสสำหรับฟังก์ชันเหล่านี้:
interface IChild
{
IContainer Parent { get; set; }
}
internal interface IContainer
{
void AddChild<T>(T child) where T : IChild;
void RemoveChild<T>(T child) where T : IChild;
IChild GetChild(int index);
}
WinForms ควบคุมข้อความที่แสดงดังนั้นสิ่งนี้จะเข้าสู่อินเตอร์เฟส:
interface ITextHolder
{
string Text { get; set; }
int TextPositionX { get; set; }
int TextPositionY { get; set; }
int TextWidth { get; }
int TextHeight { get; }
void DrawText();
}
การควบคุมบางอย่างสามารถเชื่อมต่อภายในการควบคุมหลักของพวกเขาดังนั้น:
enum Docking
{
None, Left, Right, Top, Bottom, Fill
}
interface IDockable
{
Docking Dock { get; set; }
}
... และตอนนี้เรามาสร้างคลาสที่เป็นรูปธรรมกันบ้าง:
class Panel : Control, IDockable, IContainer, IChild {}
class Label : Control, IDockable, IChild, ITextHolder {}
class Button : Control, IChild, ITextHolder, IDockable {}
class Window : Control, IContainer, IDockable {}
"ปัญหา" แรกที่ฉันนึกได้ก็คืออินเทอร์เฟซถูกตั้งค่าโดยทั่วไปเมื่อพวกเขาได้รับการเผยแพร่ แต่สมมติว่าฉันจะสามารถทำให้อินเทอร์เฟซของฉันดีพอที่จะหลีกเลี่ยงการเปลี่ยนแปลงในอนาคต
อีกปัญหาที่ฉันเห็นในการออกแบบนี้คือทุกคลาสเหล่านี้จะต้องใช้อินเทอร์เฟซของมันและการทำซ้ำของรหัสจะเกิดขึ้นอย่างรวดเร็ว ตัวอย่างเช่นในฉลากและปุ่มวิธี DrawText () มาจากอินเทอร์เฟซ ITextHolder หรือในทุก ๆ คลาสที่ได้รับจากการจัดการ IContainer ของลูก
โซลูชันของฉันสำหรับปัญหานี้คือการใช้ฟังก์ชัน "ซ้ำซ้อน" นี้ในอะแดปเตอร์เฉพาะและโอนสายไปยังพวกเขา ดังนั้นทั้งป้ายและปุ่มจะมีสมาชิก TextHolderAdapter ที่จะเรียกว่าภายในวิธีการสืบทอดมาจากอินเตอร์เฟซ ITextHolder
ฉันคิดว่าการออกแบบนี้ควรป้องกันฉันไม่ให้มีฟังก์ชั่นทั่วไปหลายอย่างในคลาสพื้นฐานซึ่งสามารถพองได้อย่างรวดเร็วด้วยวิธีเสมือนจริงและ "รหัสเสียง" ที่ไม่จำเป็น การเปลี่ยนแปลงพฤติกรรมจะทำได้โดยการขยายอะแดปเตอร์และไม่ใช่คลาสที่ได้รับการควบคุม
ฉันคิดว่าสิ่งนี้เรียกว่ารูปแบบ "กลยุทธ์" และแม้ว่าจะมีคำถามและคำตอบหลายล้านข้อในหัวข้อนั้นฉันอยากจะขอความคิดเห็นจากคุณเกี่ยวกับสิ่งที่ฉันคำนึงถึงสำหรับการออกแบบนี้และข้อบกพร่องที่คุณสามารถคิดถึงได้ แนวทางของฉัน
ฉันควรเพิ่มว่ามีโอกาสเกือบ 100% ที่ความต้องการในอนาคตจะเรียกชั้นเรียนใหม่และฟังก์ชั่นใหม่
IChild
ดูเหมือนชื่อที่น่ากลัว
System.ComponentModel.Component
หรือSystem.Windows.Forms.Control
หรือจากคลาสพื้นฐานอื่น ๆ ที่มีอยู่? ทำไมคุณต้องสร้างลำดับชั้นการควบคุมของคุณเองและกำหนดหน้าที่ทั้งหมดเหล่านี้อีกครั้งตั้งแต่เริ่มต้น?