제이온

[ออบเจกต์] บทที่ 1 วัตถุ การออกแบบ

สร้าง: 2024-04-28

สร้าง: 2024-04-28 13:45

บทนำ

โรเบิร์ต แอล. กลาสส์ ได้โต้แย้งว่าการปฏิบัติจริงนั้นมาก่อนทฤษฎี โดยเฉพาะอย่างยิ่งในด้านการพัฒนาซอฟต์แวร์ การปฏิบัติจริงเป็นสาขาที่โดดเด่นกว่าทฤษฎี โดยที่นักพัฒนาจะได้รับประโยชน์มากที่สุดเมื่อได้ลงมือเขียนโค้ดจริง ดังนั้นเราจึงจะพิจารณาโปรแกรมง่ายๆ สักตัวก่อน โดยละทิ้งทฤษฎีและแนวคิดไว้ก่อนชั่วคราว


การสร้างแอปพลิเคชันจำหน่ายตั๋ว

  • เราต้องการจัดกิจกรรมเล็กๆ เพื่อประชาสัมพันธ์โรงละครขนาดเล็ก
    • เนื้อหาของกิจกรรม: จัดการจับฉลากเพื่อมอบบัตรเชิญให้กับผู้ชมที่ได้รับเลือก เพื่อเข้าชมการแสดงโดยไม่เสียค่าใช้จ่าย
  • เราจำเป็นต้องแยกผู้ชมที่ได้รับรางวัลจากกิจกรรมออกจากผู้ที่ไม่ได้รับรางวัล
    • ผู้ชมที่ได้รับรางวัลจากกิจกรรม: แลกเปลี่ยนบัตรเชิญเป็นตั๋วเข้าชม
    • ผู้ชมที่ไม่ได้รับรางวัลจากกิจกรรม: ซื้อตั๋วโดยใช้เงินสด



ปัญหาอยู่ที่ไหน

โรเบิร์ต มาร์ติน ได้อธิบายถึงฟังก์ชันทั้งสามอย่างที่โมดูลซอฟต์แวร์ (ไม่ว่าจะมีขนาดเท่าใดก็ตาม เช่น คลาส แพ็กเกจ หรือไลบรารี องค์ประกอบใดๆ ที่ประกอบเป็นโปรแกรม)


  • ทำงานได้อย่างถูกต้องในระหว่างการรัน
  • มีไว้เพื่อการแก้ไข
    • ต้องสามารถแก้ไขได้โดยใช้ขั้นตอนง่ายๆ
  • สื่อสารกับผู้ที่อ่านโค้ด
    • นักพัฒนาต้องสามารถอ่านและทำความเข้าใจได้ง่าย


แอปพลิเคชันจำหน่ายตั๋วที่กล่าวถึงก่อนหน้านี้ตรงตามข้อจำกัดแรกที่ว่าทำงานได้อย่างถูกต้อง แต่ไม่สามารถตรงตามวัตถุประสงค์ด้านความสะดวกในการแก้ไขและการสื่อสารได้


โค้ดที่ไม่ตรงตามที่คาดหวัง

ลองมาดูเหตุผลที่ไม่ตรงตามวัตถุประสงค์ด้านการสื่อสารกัน


  • สิ่งที่เมธอด enter() ของคลาส Theater ทำ
    • โรงละครจะเปิดกระเป๋าของผู้ชมเพื่อตรวจสอบว่ามีบัตรเชิญอยู่ภายในหรือไม่
    • หากพบว่ามีบัตรเชิญอยู่ภายในกระเป๋า โรงละครจะสั่งให้พนักงานขายตั๋ว ย้ายตั๋วที่เก็บไว้ในห้องจำหน่ายตั๋วไปไว้ในกระเป๋าของผู้ชม
    • หากไม่พบว่ามีบัตรเชิญอยู่ภายในกระเป๋า โรงละครจะหยิบเงินสดออกจากกระเป๋าของผู้ชมตามจำนวนเงินค่าตั๋ว ซื้อตั๋ว และใส่ตั๋วลงในกระเป๋าของผู้ชม
  • ในมุมมองของผู้ชม ผู้ชมจะต้องนั่งเฝ้าดูโรงละคร ซึ่งเป็นบุคคลที่สาม เปิดกระเป๋าของตนเองหยิบเงินของตนเอง และใส่ตั๋วลงไป
  • ในมุมมองของพนักงานขายตั๋ว พนักงานขายตั๋วจะต้องนั่งเฝ้าดูโรงละคร ซึ่งเป็นบุคคลที่สาม จัดการกับตั๋วและเงินสดในห้องจำหน่ายตั๋วโดยไม่ได้รับอนุญาต
  • โค้ดที่เข้าใจได้ง่าย หมายถึงโค้ดที่การทำงานไม่เบี่ยงเบนไปจากที่เราคาดหวังมากนัก แต่โรงละครในตัวอย่างนี้เบี่ยงเบนไปจากที่เราคาดหวัง
    • ผู้ชมควรหยิบเงินสดจากกระเป๋าของตนเองเพื่อจ่ายให้กับพนักงานขายตั๋ว และรับตั๋วจากพนักงานขายตั๋ว
    • พนักงานขายตั๋วควรหยิบตั๋วจากห้องจำหน่ายตั๋ว มอบให้กับผู้ชม และรับเงินจากผู้ชมเพื่อเก็บไว้ในห้องจำหน่ายตั๋ว
  • นอกจากนี้ เพื่อให้เข้าใจเมธอด enter() เราต้องจดจำรายละเอียดต่างๆ มากมาย
    • Audience มี Bag
    • Bag บรรจุเงินสดและตั๋ว
    • TiketSellet ขายตั๋วจาก TicketOffice และ TicketOffice เก็บเงินสดและตั๋ว


โค้ดที่อ่อนไหวต่อการเปลี่ยนแปลง

เมธอด enter() สันนิษฐานเงื่อนไข 2 ข้อ

  • ผู้ชมจะพกกระเป๋าติดตัวไปเสมอเพื่อเก็บเงินสดและบัตรเชิญ
  • พนักงานขายตั๋วจะขายตั๋วเฉพาะที่ห้องจำหน่ายตั๋วเท่านั้น


แล้วสถานการณ์ต่อไปนี้ล่ะ

  • ผู้ชมอาจไม่มีกระเป๋า
  • ผู้ชมอาจใช้บัตรเครดิตแทนเงินสด
  • พนักงานขายตั๋วอาจขายตั๋วข้างนอกห้องจำหน่ายตั๋วได้


ยกตัวอย่างเช่น หากต้องการตรงตามข้อกำหนดแรก เราต้องลบคลาส Bag ของ Audience และแก้ไขเมธอด enter() ของคลาส Theater เนื่องจากคลาส Theater ขึ้นอยู่กับข้อมูลรายละเอียดมากเกินไป เช่น ผู้ชมมีกระเป๋า และพนักงานขายตั๋วขายตั๋วเฉพาะที่ห้องจำหน่ายตั๋วเท่านั้น หากมีการเปลี่ยนแปลงข้อมูลรายละเอียดใดๆ แม้เพียงรายละเอียดเดียว เราจำเป็นต้องแก้ไขทั้งคลาสที่เกี่ยวข้องและคลาสที่ขึ้นอยู่กับคลาสดังกล่าว (เช่น Theater)


นี่คือปัญหาที่เกี่ยวข้องกับการพึ่งพาระหว่างออบเจ็กต์ และการพึ่งพาบ่งบอกถึงผลกระทบจากการเปลี่ยนแปลง อย่างไรก็ตาม เป้าหมายของการออกแบบเชิงวัตถุคือการสร้างชุมชนของออบเจ็กต์ที่ทำงานร่วมกันโดยการพึ่งพาอาศัยกัน ดังนั้นเราจึงไม่ควรพยายามกำจัดการพึ่งพาทั้งหมด แต่ควรรักษาการพึ่งพาให้น้อยที่สุดและกำจัดการพึ่งพาที่ไม่จำเป็นออกไป


กรณีที่ออบเจ็กต์พึ่งพาอาศัยกันมากเกินไป เราเรียกว่ามีความสัมพันธ์สูงโดยที่ยิ่งออบเจ็กต์สองตัวมีความสัมพันธ์สูงมากเท่าใด ก็ยิ่งมีโอกาสที่จะต้องเปลี่ยนแปลงไปพร้อมกันมากขึ้นเท่านั้น ดังนั้นเป้าหมายของการออกแบบจึงคือการลดความสัมพันธ์ระหว่างออบเจ็กต์ เพื่อให้การออกแบบมีความยืดหยุ่นในการแก้ไข


การปรับปรุงการออกแบบ

Theater ไม่จำเป็นต้องรู้ว่าผู้ชมมีกระเป๋าหรือพนักงานขายตั๋วขายตั๋วที่ห้องจำหน่ายตั๋ว Theater ต้องการเพียงให้ผู้ชมเข้ามาในโรงละครเท่านั้น ดังนั้นเราควรสร้างผู้ชมและพนักงานขายตั๋วให้เป็นอิสระต่อกัน โดยที่ผู้ชมจัดการเงินสดและบัตรเชิญในกระเป๋าของตนเอง และพนักงานขายตั๋วจัดการตั๋วและค่าตั๋วในห้องจำหน่ายตั๋วของตนเอง


เพิ่มความเป็นอิสระ

ออบเจ็กต์ที่ดำเนินการเฉพาะงานที่เกี่ยวข้องอย่างใกล้ชิด และมอบหมายงานที่ไม่เกี่ยวข้องให้กับออบเจ็กต์อื่น เราเรียกว่าออบเจ็กต์ที่มีการรวมกลุ่มสูง การสร้างออบเจ็กต์ที่เป็นอิสระที่สามารถจัดการข้อมูลของตนเองได้ จะช่วยลดความสัมพันธ์และเพิ่มการรวมกลุ่ม


การเขียนโปรแกรมเชิงกระบวนการและการเขียนโปรแกรมเชิงวัตถุ

  • การเขียนโปรแกรมเชิงกระบวนการ
    • เมธอด enter() ของ Theater เป็นกระบวนการ และ Audience, TicketSeller, Bag, TicketOffice เป็นข้อมูล
    • การวางกระบวนการและข้อมูลในโมดูลที่แยกจากกัน เรียกว่าการเขียนโปรแกรมเชิงกระบวนการ
    • มีโค้ดที่ขัดแย้งกับสัญชาตญาณของเรามากมาย (เช่น ผู้ชมจัดการเงินและบัตรเชิญด้วยตนเอง)
    • ยากที่จะจำกัดผลกระทบจากการเปลี่ยนแปลงข้อมูล
    • จัดการความรับผิดชอบแบบรวมศูนย์ (Theater จัดการทุกอย่าง)
  • การเขียนโปรแกรมเชิงวัตถุ
    • การวางข้อมูลและกระบวนการไว้ในโมดูลเดียวกัน เรียกว่าการเขียนโปรแกรมเชิงวัตถุ
    • สามารถเขียนโค้ดที่สอดคล้องกับสัญชาตญาณของเราได้
    • สามารถจำกัดผลกระทบจากการเปลี่ยนแปลงข้อมูลได้อย่างมีประสิทธิภาพผ่านการห่อหุ้ม
    • ออบเจ็กต์แต่ละตัวรับผิดชอบตัวเอง


ยังสามารถปรับปรุงได้อีก

  • คลาส Bag ของคลาส Audience ยังคงเป็นออบเจ็กต์แบบพาสซีฟที่ถูกควบคุมโดยคลาส Audience ดังนั้นเราจึงจำเป็นต้องสร้างคลาส Bag ให้เป็นออบเจ็กต์แบบแอคทีฟ
  • TicketOffice ของคลาส TicketSeller ก็ถูกควบคุมโดย TicketSeller เช่นกัน เราจำเป็นต้องสร้าง TicketOffice ให้เป็นออบเจ็กต์แบบแอคทีฟ
    • แต่หลังจากการเปลี่ยนแปลง TicketOffice มีความสัมพันธ์กับ Audience เพิ่มขึ้น
    • การออกแบบจำเป็นต้องพิจารณาการแลกเปลี่ยนผลประโยชน์ ในกรณีนี้ เราอาจตกลงที่จะสร้าง TicketOffice ให้เป็นออบเจ็กต์แบบพาสซีฟบางส่วน เพื่อลดความสัมพันธ์กับ Audience



ไม่จริงหรอก!

  • ในโลกแห่งความเป็นจริง แม้ว่าออบเจ็กต์จะเป็นแบบพาสซีฟ แต่เมื่อเข้าสู่โลกของการเขียนโปรแกรมเชิงวัตถุ ออบเจ็กต์ทุกอย่างจะกลายเป็นแบบแอคทีฟและเป็นอิสระ
  • การใช้การเปรียบเทียบกับมนุษย์ (Anthropomorphism) เพื่อจินตนาการถึงออบเจ็กต์แบบพาสซีฟว่าเป็นสิ่งที่มีความรู้สึก สามารถหัวเราะ พูดคุย และโกรธ เป็นสิ่งที่ดี


การออกแบบเชิงวัตถุ

ทำไมต้องออกแบบ

  • การออกแบบคือการจัดวางโค้ด
  • การออกแบบที่ดีคือการที่สามารถทำงานตามฟังก์ชันที่ต้องการในปัจจุบันได้อย่างสมบูรณ์ และสามารถรองรับการเปลี่ยนแปลงในอนาคตได้อย่างราบรื่น


การออกแบบเชิงวัตถุ

  • โค้ดที่สามารถแก้ไขได้ง่ายคือโค้ดที่เข้าใจง่าย
  • พาราไดม์เชิงวัตถุช่วยให้เราสามารถเขียนโค้ดได้ตามวิธีที่เราเห็นโลก
  • ออบเจ็กต์เป็นสิ่งที่มีความเป็นอิสระที่รับผิดชอบข้อมูลของตัวเอง
  • การออกแบบเชิงวัตถุที่ดีคือการจัดการการพึ่งพาระหว่างออบเจ็กต์ที่ทำงานร่วมกันอย่างเหมาะสม


แหล่งที่มา

  • ออบเจ็กต์

ความคิดเห็น0

[สำหรับผู้ไม่ใช่ผู้เชี่ยวชาญ ด้านการพัฒนาซอฟต์แวร์ เพื่อความอยู่รอด] 14. สรุปเนื้อหาสัมภาษณ์ทางเทคนิคที่ผู้พัฒนาซอฟต์แวร์มือใหม่ถามบ่อยสรุปคำถามทางเทคนิคที่มักถามในการสัมภาษณ์งานผู้พัฒนาซอฟต์แวร์มือใหม่ (พื้นที่หน่วยความจำ โครงสร้างข้อมูล ฐานข้อมูล ฯลฯ) หวังว่าจะเป็นประโยชน์ในการเตรียมตัวสัมภาษณ์งานด้านการพัฒนา
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

[1 วัน] สร้างเกมสนุกๆ กับ AIขอแนะนำบันทึกการพัฒนาเกมดันเจี้ยน 100 ชั้นที่สร้างด้วย Javascript, HTML, CSS โดยได้รับความช่วยเหลือจาก AI ปัจจุบันกำลังพัฒนาส่วนต่างๆ เช่น เมือง ดันเจี้ยน และระบบต่อสู้ โดยได้เสร็จสิ้นการสร้างระบบสร้างตัวละครและระบบคลังของแล้ว พรุ่งนี้จะเริ่มพัฒนาต่อสู้
꼬반
꼬반
꼬반
꼬반

November 8, 2024

29 พ.ย. 2567 ข่าวล่าช้า: สมัคร Replit แบบชำระเงิน / นิสัยการพัฒนาซอฟต์แวร์ที่ดีบทความบล็อกที่เขียนเมื่อวันที่ 29 พฤศจิกายน พ.ศ. 2567 นี้จะแบ่งปันรีวิวการสมัครสมาชิกแบบชำระเงินของ Replit และแนะนำนิสัยการพัฒนาซอฟต์แวร์ที่ดี 10 ประการ ครอบคลุมกลยุทธ์การเขียนโค้ดและการปรับโครงสร้างที่มีประสิทธิภาพ รวมถึงความสำคัญของการทดสอบ
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 29, 2024

หลักการพื้นฐาน 1 ข้อ คิดวิเคราะห์ตั้งแต่ต้นเรียนรู้วิธีการใช้หลักการพื้นฐาน 1 ข้อของอีลอน มัสก์ เพื่อค้นหาสาเหตุรากฐานของปัญหาและค้นหาวิธีแก้ปัญหาที่สร้างสรรค์ ลองท้าทายตัวเองด้วยการตั้งคำถามและตั้งข้อสงสัยตั้งแต่ต้นจนจบเพื่อแก้ปัญหา
울림
울림
울림
울림

March 18, 2024

เรื่องราวการพัฒนาโครงการ LegiNote ตอนที่ 2 - สแตกเทคโนโลยีและเวิร์กเกอร์บทความตอนที่สองของเรื่องราวการพัฒนาโครงการ LegiNote ซึ่งจะกล่าวถึงการพัฒนาเวิร์กเกอร์โดยใช้ภาษา Go เนื้อหาครอบคลุมการนำไปใช้ในการรวบรวมและอัปเดตข้อมูล รวมถึงการออกแบบโครงสร้างของโครงการ
statpan
statpan
statpan
statpan

August 20, 2024

ปรากฏการณ์มนุษย์ พื้นฐานของการตัดสินใจทางธุรกิจ -2บทความนี้แนะนำแนวทางการให้ความสำคัญกับปรากฏการณ์มนุษย์เป็นพื้นฐานในการตัดสินใจทางธุรกิจ เรียนรู้วิธีการค้นหาโอกาสใหม่ๆ โดยเน้นที่พฤติกรรมและความต้องการของลูกค้า แทนที่จะมุ่งเน้นไปที่เมกะเทรนด์
Byungchae Ryan Son
Byungchae Ryan Son
Byungchae Ryan Son
Byungchae Ryan Son

May 7, 2024