ผู้คนจำนวนมากในประเทศจีนถือว่า Delphi เป็นเครื่องมือในการพัฒนาที่พวกเขาชื่นชอบ เหตุผลก็คือเพราะว่า Delphi ให้คุณสมบัติมากมายแก่นักพัฒนา: การพัฒนาเชิงวัตถุ การออกแบบอินเทอร์เฟซแบบภาพ ส่วนประกอบที่หลากหลาย และการพกพาได้หลายแพลตฟอร์ม (คุณสมบัติใหม่ของ Delphi6)
แต่สำหรับผู้เริ่มต้น การคิดเชิงวัตถุอาจไม่ใช่ความรู้สึกที่ยิ่งใหญ่ที่สุดที่ Delphi มอบให้พวกเขา การออกแบบอินเทอร์เฟซแบบภาพและส่วนประกอบที่หลากหลายและหลากหลายทำให้เกิดความประทับใจที่ลึกซึ้งและน่าจดจำที่สุด ผลที่ตามมาที่สำคัญก็คือ ผู้เริ่มต้นมักจะมุ่งเน้นไปที่การใช้ส่วนประกอบ VCL ที่มีอยู่ซึ่งจัดทำโดย Delphi มาเป็นเวลานาน ในขณะที่ละเลยที่จะคิดถึงผลกระทบของการคิดเชิงวัตถุต่อ Delphi ทั้งหมด ความหมายที่มีอยู่ในสถาปัตยกรรมส่วนประกอบ ระบบ.
โค้ดต่อไปนี้ประกอบด้วยข้อผิดพลาดทั่วไปประการหนึ่งที่ผู้เริ่มต้นมักทำ แม้ว่าข้อผิดพลาดนี้จะไม่ใช่ข้อผิดพลาดทางไวยากรณ์ แต่ก็เผยให้เห็นว่าการคิดเชิงวัตถุของผู้ใช้จำเป็นต้องได้รับการเสริมสร้างความเข้มแข็ง:
var
แบบฟอร์ม 1: TForm1;
การดำเนินการ
{$R *.dfm}
ขั้นตอน TForm1.Button1Click (ผู้ส่ง: TObject);
เริ่ม
ShowMessage(Form1.Caption); // <-- มีปัญหาบางประการกับการใช้ Form1 ที่นี่
จบ;
ดูเหมือนว่าจะไม่มีอะไรผิดปกติกับโค้ดประเภทนี้ตั้งแต่แรกเห็น อย่างไรก็ตาม การปรากฏตัวของ Form1 ที่นี่ค่อนข้างไม่สมเหตุสมผล แน่นอนว่าโค้ดนี้ถูกเขียนขึ้นเพื่อใช้เมธอด ButtonClick ของ TForm1 และ Form1 ซึ่งเป็นอินสแตนซ์ของคลาส TForm1 นั้นจริงๆ แล้วถูกเขียนลงในการนำคลาสไปใช้จริงหรือไม่ สำหรับการคิดเชิงวัตถุนั้นง่ายมากและสามารถเขียนได้สองวิธี:
1. ShowMessage(Self.Caption); // <-- วิธีการเขียนนี้มีความชัดเจนมาก
2. ShowMessage(Caption); // <-- วิธีการเขียนที่นี่เหมือนกับด้านบน แต่ละเว้นคำหลัก Self
เนื้อหาหลักสามประการของการคิดเชิงวัตถุคือการห่อหุ้ม การสืบทอด และความหลากหลาย ปัญหาที่แสดงโดยตัวอย่างข้างต้นคือปัญหาของการห่อหุ้ม ตัวอย่างที่คล้ายกันได้แก่:
var
แบบฟอร์ม 1: TForm1;
-
var
แบบฟอร์ม 2: TForm2;
ขั้นตอน TForm1.Button1Click (ผู้ส่ง: TObject);
เริ่ม
Form2.Show; // <-- เนื่องจากเป็นตัวแปรส่วนกลาง การใช้ Form2 ที่นี่จึงทำให้เกิดความสับสนเช่นกัน
จบ;
ตัวอย่างข้างต้นอาจเป็นเรื่องทั่วไปมากกว่า ในกรณีส่วนใหญ่ ในโปรเจ็กต์ TForm1 และ TForm2 อาจมีเพียงหนึ่งอินสแตนซ์เท่านั้น ดังนั้นโค้ดดังกล่าวจึงถือว่าผ่านได้ แต่ในแง่ที่เข้มงวด มันไม่เป็นไปตามข้อกำหนดของการห่อหุ้ม อ้างถึงรหัสต่อไปนี้:
พิมพ์
TForm1 = คลาส (TForm)
Button1: T ปุ่ม;
ขั้นตอน Button1Click (ผู้ส่ง: TObject);
ส่วนตัว
{ประกาศส่วนตัว}
Fถัดไป: TForm;
สาธารณะ
{ประกาศสาธารณะ}
คุณสมบัติ NextForm: TForm อ่าน FNext เขียน FNext;
จบ;
var
แบบฟอร์ม 1: TForm1;
การดำเนินการ
ใช้หน่วยที่ 2;
{$R *.dfm}
ขั้นตอน TForm1.Button1Click (ผู้ส่ง: TObject);
เริ่ม
ถ้าได้รับมอบหมาย (FNext) แล้ว
TForm2(FNext).แสดง;
จบ;
จบ.
//ต่อไปนี้เป็นเนื้อหาของไฟล์โครงการ:
โปรแกรมโปรเจ็กต์1;
การใช้งาน
แบบฟอร์ม
Unit1 ใน 'Unit1.pas' {Form1},
Unit2 ใน 'Unit2.pas' {Form2};
{$R *.เรส}
เริ่ม
แอปพลิเคชันเริ่มต้น;
แอปพลิเคชัน CreateForm (TForm1, Form1);
แอปพลิเคชัน CreateForm (TForm2, Form2);
Form1.NextForm := Form2; // <-- เพิ่มประโยคนี้เพื่อให้โค้ดไม่ตรงตามข้อกำหนดของการห่อหุ้ม
แอปพลิเคชันเรียกใช้;
จบ.
ส่งตัวชี้ Form2 ไปที่ Form1 เป็นคุณลักษณะของ Form1 ด้วยวิธีนี้ Form1 จะสอดคล้องกับหลักการของการห่อหุ้มเมื่อโทร! แน่นอนว่ารหัสเหล่านี้มีไว้เพื่อสะท้อนแนวคิดของการห่อหุ้มเท่านั้น ในทางปฏิบัติ คุณสามารถตัดสินใจได้ว่าต้องการปรับใช้ให้ละเอียดตามนิสัยส่วนตัวของคุณหรือไม่ แต่ความคิดแบบนี้น่าจะหยั่งรากลึกในใจ... (ยังไม่จบ มีต่อ)
บทความเพิ่มเติม