1. การนำออบเจ็กต์ทางธุรกิจไปใช้ คลาสที่ห่อหุ้มกฎเกณฑ์ทางธุรกิจเป็นพื้นฐานของการเขียนโปรแกรมเชิงวัตถุอย่างแท้จริง ในบทความนี้ เราจะกล่าวถึงทุกแง่มุมของการเขียนโปรแกรมและตั้งคำถามถึงวิธีการเขียนโปรแกรม Delphi ตามปกติของเรา แนวคิดพื้นฐานเบื้องหลังวิธีการออกแบบเหล่านี้คือการห่อหุ้ม: การออกแบบชุดของคลาสที่มีอินเทอร์เฟซ (วิธีการ) ที่กำหนดไว้อย่างชัดเจนซึ่งมีวิธีดำเนินการกับคุณสมบัติของตน แนวคิดนี้จะถูกนำมาใช้ตลอดทั้งโปรแกรมและมีผลกระทบอย่างมากต่อวิธีการบันทึกและนำเสนอข้อมูล ฉันอยากจะแนะนำผู้อ่านให้รู้จักกับบทความของ Francis Glassborow เกี่ยวกับ C ++ แม้ว่าภาษาจะแตกต่างกัน แต่แนวคิดการออกแบบชั้นเรียนที่ยอดเยี่ยมก็ไม่ขึ้นอยู่กับภาษา โปรแกรมส่วนใหญ่ที่เขียนด้วย Delphi ในปัจจุบันไม่ใช่เชิงวัตถุ เพียงเพราะมีโมเดลวัตถุในภาษาและใช้คลาสดั้งเดิมหรือคลาสใหม่ นี่ไม่ได้หมายความว่าโปรแกรมจะเป็นเชิงวัตถุอย่างแท้จริง การใช้โค้ดซ้ำจะสิ้นสุดลงเมื่อมีการลากการควบคุมของบริษัทอื่นไปยังหน้าต่าง แต่การพึ่งพาซึ่งกันและกันระหว่างหน้าต่างและหน่วยจะขยายอย่างรวดเร็ว (!!!) หากคุณต้องการเปลี่ยนพื้นฐานของโปรแกรมในอนาคต (เช่น เปลี่ยนไปใช้ฐานข้อมูลอื่นหรือเปลี่ยนจากโครงสร้าง 2 tier ไปเป็น 3 tier) ก็จะถูกขัดขวางอย่างมากหรือมีราคาแพง หากโปรแกรมถูกเขียนในลักษณะเชิงวัตถุอย่างแท้จริง มันจะสะดวกมากกว่าที่จะจำกัด แน่นอนว่าการเขียนโปรแกรมดังกล่าวจำเป็นต้องมีการปรับปรุงแนวคิด และในช่วงเริ่มต้นยังขาดประสิทธิภาพการทำงาน ทีมพัฒนาส่วนใหญ่ไม่เต็มใจที่จะทำสิ่งนี้หรือพิจารณาเรื่องนี้ ฉันหวังว่าในบทความนี้ ฉันจะแสดงให้คุณเห็นถึงวิธีการเขียนโปรแกรมที่ดีขึ้น ผลลัพธ์ที่ได้คือระบบที่เชื่อถือได้มากขึ้น บำรุงรักษาง่าย มีสไตล์สม่ำเสมอ ยืดหยุ่น นำกลับมาใช้ใหม่ได้ และทำงานได้ดีกว่าโปรแกรมที่เขียนด้วยวิธีเดิมๆ โดยเฉพาะอย่างยิ่งสำหรับโปรแกรมขนาดใหญ่ โปรแกรมที่มีโค้ดที่ชัดเจนและเชิงวัตถุอย่างแท้จริงจะต้องใช้ทรัพยากรการบำรุงรักษาน้อยกว่าโปรแกรมเดียวกันที่เขียนด้วยวิธีดั้งเดิม ความน่าเชื่อถือที่มากขึ้นของโปรแกรมเชิงวัตถุนั้นมาจากข้อเท็จจริงที่ว่าข้อมูลและการดำเนินการถูกห่อหุ้มไว้ในคลาสที่กำหนดไว้อย่างดี คอมไพลเลอร์บังคับใช้คลาส วิธีการ และคุณสมบัติที่ถูกต้องในโค้ดผ่านการตรวจสอบประเภทที่มีประสิทธิภาพ และไม่ควรมีความเป็นไปได้ที่จะเข้าใจผิดจุดประสงค์ของโค้ดหากการเปลี่ยนแปลงในอนาคตส่งผลต่อโปรแกรมทั้งหมด เมื่อใช้คลาสอย่างถูกต้อง ความสัมพันธ์ระหว่างคลาสเหล่านั้นจะอธิบายได้ในตัว และโค้ดส่วนใหญ่จะเน้นไปที่เนื้อหาของโปรแกรม แทนที่จะคิดถึงรายละเอียด เช่น วิธีเก็บรักษาข้อมูล ความเรียบง่ายและความสม่ำเสมอตลอดทั้งโค้ดจะปรับปรุงความสามารถในการบำรุงรักษาโปรแกรมได้อย่างมาก ดังที่เราจะได้เห็น การใช้การสืบทอดคลาสอย่างกว้างขวางจะช่วยเพิ่มผลผลิตและความน่าเชื่อถือ และเพิ่มความสม่ำเสมอ ความสอดคล้องเหล่านี้สะท้อนให้เห็นในโค้ดที่แสดง รวมถึงพฤติกรรมของคลาส วิธีการจัดเก็บข้อมูล และวิธีที่อินเทอร์เฟซผู้ใช้นำเสนอข้อมูล เนื่องจากฟังก์ชันการทำงานส่วนใหญ่มีให้ในคลาสพื้นฐาน จึงเป็นไปได้ที่จะเปลี่ยนโปรแกรมโดยพื้นฐานโดยการเปลี่ยนพฤติกรรมอย่างรวดเร็ว (ตัวอย่างเช่น อินเทอร์เฟซการโต้ตอบกับผู้ใช้ถูกเปลี่ยนจากรูปแบบที่ขับเคลื่อนด้วยหน้าต่างเป็นแบบ HTML) คลาสพื้นฐานเหล่านี้สามารถออกแบบให้เป็นอิสระจากโปรแกรม ดังนั้นโปรแกรมตัวที่สองที่คล้ายกันจะได้รับการเพิ่มประสิทธิภาพการทำงานทันที ชุดคลาสพื้นฐานที่ดีสามารถปรับปรุงได้มากถึง 50% สำหรับโปรแกรมขนาดเล็กในแง่ของเวลา ค่าใช้จ่าย และความน่าเชื่อถือ สิ่งแรกที่ต้องเน้นคือการเปลี่ยนไปใช้การพัฒนาเชิงวัตถุไม่ใช่เรื่องเล็กน้อย เป็นครั้งแรกที่คุณควรตรวจสอบให้แน่ใจว่าคุณได้รับความช่วยเหลือ หรือโปรแกรมมีขนาดเล็กและไม่มีกำหนดเวลาการส่งมอบเร่งด่วนเช่นกัน สังเกตว่า Object-Oriented (OO) วิธีแก้ปัญหาไม่ใช่การบอกว่าคลาสไหนควรใช้และคลาสไหนไม่ควรใช้ในโปรแกรม หากบริษัทพัฒนาการควบคุมด้วยภาพของตนเอง หรือใช้การควบคุมด้วยภาพจากภายนอก คลาสหลักในการออกแบบโปรแกรมเชิงวัตถุก็คือการพิจารณาว่าคลาสใดที่จำเป็น นี่เป็นขั้นตอนพื้นฐานอย่างยิ่ง ขึ้นอยู่กับการรับประกันทางเทคนิคของการพัฒนาอื่นๆ เนื่องจากข้อผิดพลาดในระยะแรกๆ จะต้องเสียค่าใช้จ่ายสูงในการแก้ไข เมื่อออกแบบคลาสของเรา โดยทั่วไปเรามุ่งมั่นที่จะบรรลุการมีเพศสัมพันธ์ต่ำและการทำงานร่วมกันสูง - คลาสมีความเป็นอิสระมากที่สุดเท่าที่จะเป็นไปได้ แต่สามารถนำมารวมกันในลักษณะที่ทรงพลังได้ วิธีหนึ่งที่จะบรรลุเป้าหมายนี้คือการแบ่งชั้นเรียนออกเป็นหมวดหมู่ต่างๆ ตามบทบาทที่แตกต่างกันในโปรแกรม การเลือกบทบาทที่ถูกต้องจะส่งผลให้มีชุดคลาสที่สอดคล้องกัน มีหลักการพื้นฐานที่สอดคล้องกันในการออกแบบบทบาทของคลาส คือ การแบ่งความรับผิดชอบของคลาสออกเป็นการนำเสนอ การประยุกต์ และการจัดเก็บข้อมูลแบบถาวร (โดยทั่วไปจะอยู่ในฐานข้อมูล) แม้ว่านี่จะเหมือนกับการแบ่งพาร์ติชันโปรแกรมฐานข้อมูลสามระดับ แต่สิ่งสำคัญคือต้องทราบว่าแนวคิดการแบ่งพาร์ติชันนี้สามารถนำไปใช้ในสภาพแวดล้อมที่หลากหลาย: ตั้งแต่โปรแกรมชิปตัวเดียวไปจนถึงโปรแกรมหลายระดับแบบกระจาย กลุ่มของคลาสที่ประกอบเป็นตรรกะของแอปพลิเคชันมีหน้าที่รับผิดชอบงานที่ยากที่สุด เช่น การตอบสนองต่อคำขอให้ดำเนินการของผู้ใช้และการประมวลผลข้อมูล คลาสบางคลาสในเลเยอร์นี้แสดงถึงเอนทิตีในโลกแห่งความเป็นจริงและสร้างแบบจำลองโดยระบบ คลาสเหล่านี้มักเรียกว่า "คลาสธุรกิจ" หรือ "คลาสโดเมนปัญหา" พวกมันเป็นส่วนสำคัญของโปรแกรมเชิงวัตถุ และเนื่องจากคลาสอื่น ๆ จะสนับสนุนคลาสเหล่านี้ในทางใดทางหนึ่ง พวกมันจึงกลายเป็นจุดสนใจของนักพัฒนาทั้งหมด การระบุว่าวัตถุทางธุรกิจใดที่มีอยู่ในโปรแกรมนั้น โดยทั่วไปเป็นเรื่องของประสบการณ์และสัญชาตญาณ แม้ว่าจะมีระเบียบวินัยทั้งหมด (หรือศิลปะ) ในกระบวนการนี้ก็ตาม มีข้อดีของการวางแนววัตถุมากกว่าเทคนิคแบบดั้งเดิม เช่น SSADM(1) ตลอดการวิเคราะห์ การออกแบบ และกระบวนการดูแลรักษาเอนทิตี: แต่ละออบเจ็กต์ทางธุรกิจสามารถแสดงผ่านการวิเคราะห์เชิงวัตถุ (OOA) การออกแบบเชิงวัตถุ (OOD) และการเขียนโปรแกรมเชิงวัตถุ (OOP) เราจะสำรวจเทคนิคบางอย่างในการระบุเป้าหมายทางธุรกิจที่เหมาะสมในภายหลัง ขั้นแรกเราถือว่ากระบวนการต่อไปนี้เสร็จสิ้นแล้ว การสื่อสารระหว่างกันของคลาสระหว่างเลเยอร์ต่างๆ (การนำเสนอ การประยุกต์ และการคงอยู่) ได้รับการกำหนดอย่างชัดเจนและเชื่อมโยงถึงกัน ความสัมพันธ์ระหว่างคลาสเหล่านี้แสดงในรูปที่ 1 ลูกศรในรูปแสดงว่าคลาสในเลเยอร์เดียวกันสามารถเรียกเมธอดในคลาสอื่นได้ รูปภาพนี้ยังแสดงให้เห็นว่าคลาสของเลเยอร์การนำเสนอ (ส่วนต่อประสานผู้ใช้) สามารถดำเนินการเลเยอร์แอปพลิเคชันหรือคลาสอื่น ๆ ในส่วนต่อประสานผู้ใช้ได้ เลเยอร์แอปพลิเคชัน (ออบเจ็กต์ทางธุรกิจ) สามารถดำเนินการคลาสของเลเยอร์แอปพลิเคชันและเรียกวิธีการคงอยู่ได้ เลเยอร์การคงอยู่ตอบสนองต่อคำขอของเลเยอร์แอปพลิเคชันเท่านั้น ออบเจ็กต์ทางธุรกิจ เพื่อสาธิตวิธีการนำออบเจ็กต์ทางธุรกิจไปใช้ เราจะเห็นโปรแกรมที่เรียบง่ายพร้อมด้วยสินค้าคงคลัง ลูกค้า และเอนทิตีคำสั่งซื้อ (บริษัทจัดหาสินค้าจำนวนหนึ่ง และลูกค้าซื้อสินค้าเหล่านี้) การวิเคราะห์เบื้องต้นของเราระบุว่าจำเป็นต้องมีวัตถุทางธุรกิจสามรายการเพื่อเป็นตัวแทนของเอนทิตีเหล่านี้ โปรแกรม Delphi ของเราจะมีสามคลาส: TStockItem, TCustomer และ Torder อินเทอร์เฟซสาธารณะของคลาสเหล่านี้แสดงอยู่ในรายการ 1 ควรชี้ให้เห็นว่าคุณลักษณะของคลาสเหล่านี้ถูกเปิดเผยสู่ภายนอกผ่านคุณสมบัติ (คุณสมบัติ): นี่คือการออกแบบคลาสที่เรียบง่ายและเป็นประโยชน์และควบคุมการเข้าถึงจากภายนอกผ่านคุณสมบัติ นอกจากนี้คุณสมบัติเหล่านี้ควรอยู่ในพื้นที่เผยแพร่ของชั้นเรียน (ด้วยเหตุผลที่จะกล่าวถึงในภายหลัง) และได้รับการกำหนดค่าเริ่มต้นที่เหมาะสม แม้ว่าคุณสมบัติคุณสมบัติเหล่านี้จะถูกใช้เฉพาะเมื่อคลาสสตรีมมิ่งเท่านั้น แต่คุณสมบัติเหล่านี้จะทำให้แต่ละคุณสมบัติมีค่าเริ่มต้นที่เหมาะสม และทำให้โค้ดอธิบายได้ด้วยตนเองมากขึ้น กรอบการทำงานระดับเฟิร์สคลาส ในขั้นเริ่มต้นของการพัฒนาโปรแกรม เราได้ระบุและดำเนินการวัตถุประสงค์ทางธุรกิจสามประการ วัตถุทั้งสามนี้มีบทบาทร่วมกัน: เป็นตัวแทนของสิ่งมีชีวิตในโลกแห่งความเป็นจริงในทางใดทางหนึ่ง ดังนั้นเราจึงต้องการให้พวกเขามีคุณสมบัติที่คล้ายคลึงกันและระดับที่เหมาะสมกับเอนทิตีในโลกแห่งความเป็นจริง เราจะให้คลาสพื้นฐานทั่วไปแก่แต่ละอ็อบเจ็กต์ที่เรียกว่า TPDObject (อ็อบเจ็กต์โดเมนปัญหา) เมื่อเวลาผ่านไป เราจะเพิ่มวิธีการและคุณสมบัติสาธารณะให้กับคลาสนี้ และ TPDObject จะยังคงขยายต่อไป ควรสังเกตว่า TPDObject ไม่ควร (ไม่เคย) มีองค์ประกอบใด ๆ ที่เกี่ยวข้องกับแอปพลิเคชันเฉพาะ เนื่องจากเป็นคลาสที่ไม่ขึ้นกับโปรแกรม คลาสนั้นจะถูกวางไว้ในหน่วยอิสระและสร้างพื้นฐานของเฟรมเวิร์ก: ชุดของคลาสที่สามารถนำมาใช้ซ้ำได้ในหลาย ๆ โปรแกรม ในอนาคต กรอบงานของเราจะได้รับการขยายอย่างมากเพื่อสร้างคลาสพื้นฐานที่มีฟังก์ชันที่สำคัญไม่ขึ้นอยู่กับโปรแกรม และสามารถใช้งานได้อย่างรวดเร็วในระบบเฉพาะ TStockItem, TCustomer และ Torder ของเราเป็นออบเจ็กต์ที่ปรับแต่งสำหรับระบบเฉพาะจาก TPDObject TMyAppPDObject เป็นคลาสที่สืบทอดมาจาก TPDObject แม้ว่าส่วนของการใช้งานจะว่างเปล่า แต่ก็เป็นการสาธิตที่ดี ถ้าเราเพิ่มองค์ประกอบบางอย่างให้กับโปรแกรมเฉพาะและส่งผลกระทบต่อคลาสโดเมนปัญหาทั้งหมดในโปรแกรมเช่นนี้ ลำดับชั้นของคลาสควรจะเหมาะสมกว่า รหัสเริ่มต้นสำหรับกรอบงานแสดงอยู่ในรายการ คลาส TPDObject ยังจัดเตรียม ID แอตทริบิวต์แบบอ่านอย่างเดียวเท่านั้น ประเภทคือ TobjectID คุณลักษณะนี้ทำให้แต่ละออบเจ็กต์มีตัวระบุ: เราจะถือว่าสองอินสแตนซ์ประเภทและ ID เดียวกันเป็นออบเจ็กต์เดียวกัน ในที่นี้ ID ได้รับการจงใจประกาศให้เป็นประเภทของตัวเองเพื่อหลีกเลี่ยงการถูกกำหนดให้กับค่าประเภทมาตรฐานอื่นโดยตรง ประเภทของ TobjectID ไม่ได้ถูกเลือกโดยเฉพาะ: ที่นี่ฉันเลือกจำนวนเต็ม ซึ่งอาจเป็นคลาสเฉพาะในบางกรณี แม้ว่าการใช้คลาสเป็น ID ดูเหมือนจะเป็นแนวทางเชิงวัตถุที่บริสุทธิ์มากกว่า ขึ้นอยู่กับข้อเท็จจริงที่ว่าคลาสในโดเมนปัญหาของเราจะถูกสร้างและเผยแพร่หลายพันครั้งในระหว่างการรันโปรแกรม เพื่อหลีกเลี่ยงภาระพิเศษเมื่อสร้าง และการปล่อยวัตถุ ฉันไม่ได้ทำสิ่งนี้ (ในฐานะผู้พิถีพิถัน ฉันรวม TobjectID ใน TPDObject เป็นวัตถุคอมโพสิต) ในโค้ดมีฟังก์ชันคู่หนึ่งที่แปลงสตริงเป็นประเภทการระบุวัตถุของเรา และค่าคงที่ที่ทำหน้าที่เป็นค่าเริ่มต้นเมื่อไม่มีการกำหนด มีหลายคลาสที่มีการกล่าวถึงการระบุวัตถุ: บางคนบอกว่าวัตถุทางธุรกิจทั้งหมดควรได้รับการระบุตัวตน (แม้แต่ GUID) ซึ่งจะไม่เกิดซ้ำภายในโปรแกรมเมื่อสร้างขึ้น ในความเป็นจริง ความสามารถในการแยกแยะระหว่างออบเจ็กต์ต่างๆ ในบริบทที่กำหนดคือสิ่งที่สำคัญจริงๆ และการทำให้สิ่งนี้เรียบง่ายจะมีประสิทธิภาพที่ชัดเจนและคุณประโยชน์ของพื้นที่จัดเก็บข้อมูล คำถามเกี่ยวกับข้อกำหนด: เพื่อเสริมสร้างแนวคิดและแนวทางปฏิบัติในการออกแบบเมื่อออกแบบกรอบงานของชั้นเรียน ฉันจะถามคำถามและขอให้ผู้อ่านคิดถึงหลักการพื้นฐานเบื้องหลังคำถามเหล่านั้น ฉันบอกว่าการออกแบบเชิงวัตถุที่แท้จริงไม่ได้ห้ามการใช้คลาสเฉพาะ แต่มีข้อยกเว้นที่สำคัญประการหนึ่ง ข้อยกเว้นนี้คืออะไร (คำตอบอยู่ในรูปที่ 1) ((( รายการ 1 - หน่วยโดเมนปัญหาเฉพาะแอปพลิเคชัน (ย่อ) )))หน่วย ProblemDomain;interfaceuses Framework;type TMyAppPDObject = class (TPDObject) end; TStockItem = class ( TMyAppPDObject ) ชื่อคุณสมบัติที่เผยแพร่: String; คุณสมบัติ quantityInStock: ค่าเริ่มต้นที่สำคัญ 0; คุณสมบัติ TradePrice: สกุลเงิน; คุณสมบัติ RetailPrice: สกุลเงิน; TCustomer = class (TMyAppPDObject) … ; TOrder = class (TMyAppPDObject) … ;implementationend.((( รายการสิ้นสุด 1 )))((( รายการ 2 - หน่วย Framework ที่ไม่ขึ้นอยู่กับแอปพลิเคชัน ))) unit Framework; interfaceconst NotAssigned = 0; ประเภท TObjectID = ประเภทจำนวนเต็ม TPDObject = คลาสส่วนตัว FID: TObjectID; ID ทรัพย์สินสาธารณะ: TObjectID อ่านค่าเริ่มต้น FID NotAssigned; end;function StrToID (ค่า: String): TObjectID;function IDToStr (ค่า: TObjectID): String;implementation…end.((( End Listing 2 )))(1) SSADM (Structured Systems Analysis & Systems Design) ก่อตั้งขึ้นใน 1981 สำนักงานคอมพิวเตอร์กลางและโทรคมนาคมของรัฐบาลอังกฤษ (CCTA); เว็บไซต์: http://www.ccta.gov.uk ) พัฒนาวิธีมาตรฐานการวิเคราะห์และการออกแบบซอฟต์แวร์ Philip Brown เป็นที่ปรึกษาด้านการออกแบบระบบและนักพัฒนา ผู้นำเสนอ และผู้ฝึกสอน เขาจะส่งเสริมคุณประโยชน์ของเทคนิค OO ที่แข็งแกร่งเพื่อมอบแอปพลิเคชันที่ดียิ่งขึ้นเมื่อได้รับโอกาสต่างๆ