ตัวอย่างที่ใช้งานได้จริงเพื่อสอนแนวคิดเชิงวัตถุและการเขียนโปรแกรม (ใน python)
ฉันได้สอนนักเรียนมัธยมของฉันให้เขียนสคริปต์ python ง่ายๆ โดยใช้แนวคิดบางอย่างจาก"Automate the Boring Stuff with Python"เช่น การเปลี่ยนชื่อไฟล์ในโฟลเดอร์เป็นรูปแบบการตั้งชื่อเฉพาะ
เป้าหมายต่อไปของฉันคือการสอนแนวคิดเชิงวัตถุแก่พวกเขา และถ้าเป็นไปได้ให้ยกตัวอย่าง "ของจริง" ให้พวกเขาลองด้วยตัวเอง แต่เนื้อหาส่วนใหญ่ที่ฉันพบ (ผลการค้นหาอันดับต้น ๆ ของ Google) เกี่ยวกับการเขียนโปรแกรม OO (ไม่ใช่แค่ python) นั้นเต็มไปด้วยตัวอย่างที่ไม่ดีถ้าฉันจะพูดอย่างนั้น ฉันไม่ชอบใช้รถยนต์/ยานพาหนะหรือสัตว์/สุนัขเพื่อสอนแนวคิด OO และ OOP ให้พวกเขา
ก. น่าเบื่อ (คุณรู้จักเด็กม
. ปลาย) ข. มันไม่มีประโยชน์อะไร
C. ตามที่หนึ่งความคิดเห็นกล่าวว่า "พวกเขามีข้อบกพร่องร้ายแรง" (แต่ถ้าคุณชอบใช้ตัวอย่างสัตว์จริงๆ ให้เลือก"การออกแบบเชิงวัตถุ" นี้ )
ฉันวางแผนที่จะใช้pathlib (btw พวกเขามีแนวคิดพื้นฐานเกี่ยวกับความแตกต่างระหว่าง Windows และ UNIX แล้ว)
![](https://post.nghiatu.com/assets/images/s/jvahy.png)
การพัฒนา GUI อาจเป็นอีกตัวอย่างที่ดีในการสอน OOP แต่ฉันยังไม่ต้องการสอน GUI ให้พวกเขา
ข้อเสนอแนะใด ๆ ที่จะแนะนำ OO ด้วยตัวอย่าง "ของจริง"?
BTW ฉันไม่ใช่ผู้สนับสนุนที่แข็งแกร่งของการเขียนโปรแกรมเชิงวัตถุ แต่pathlib.Path
ชั้นเรียนเป็นนามธรรมที่มีประโยชน์โดยเฉพาะอย่างยิ่งเมื่อเทียบกับ os.path แม้ว่านักเรียนมัธยมปลายไม่น่าจะชื่นชมสิ่งนั้น
---- อัพเดท ----
ฉันพบว่าโมดูลการบันทึกหลามเป็นอีกตัวอย่างที่ดี แต่ดูเหมือนว่าซับซ้อนเกินไปสำหรับโปรแกรมเมอร์ที่ไม่มีประสบการณ์
เมื่อใช้โมดูลการเข้าสู่ระบบที่เราส่วนใหญ่ใช้ 3 วัตถุLogger, Handler, ฟอร์แมต คนตัดไม้เป็นซุ้ม , เป็นhttps://docs.python.org/3/howto/logging.html#loggers กล่าว,
ออบเจ็กต์คนตัดไม้มีงานสามเท่า ขั้นแรก พวกเขาเปิดเผยวิธีการต่างๆ กับรหัสแอปพลิเคชัน เพื่อให้แอปพลิเคชันสามารถบันทึกข้อความขณะรันไทม์ได้ ประการที่สอง ออบเจ็กต์ตัวบันทึกจะกำหนดว่าข้อความบันทึกใดที่จะดำเนินการตามความรุนแรง (สิ่งอำนวยความสะดวกในการกรองเริ่มต้น) หรือออบเจ็กต์ตัวกรอง ประการที่สาม ออบเจ็กต์ของตัวบันทึกจะส่งต่อข้อความบันทึกที่เกี่ยวข้องไปยังตัวจัดการบันทึกที่สนใจทั้งหมด
Handler เป็นตัวอย่างที่ดีในการใช้มรดก https://docs.python.org/3/howto/logging.html#useful-handlers และตัวจัดการใช้ตัวจัดรูปแบบซึ่งซ่อนความซับซ้อนของ LogRecord กับข้อความบันทึกรูปแบบ
นอกจากคลาสเหล่านี้แล้ว ยังมีฟังก์ชันระดับโมดูลอีกจำนวนหนึ่งเพื่อความสะดวกในการใช้งาน
โดยรวมแล้วเป็นตัวอย่างที่ดีของการใช้องค์ประกอบและการรวม
แต่ฉันไม่ใช่ผู้เชี่ยวชาญในโมดูลการบันทึกหลาม ฉันหวังว่าคนที่คุ้นเคยกับโมดูลการบันทึกหลามอาจเพิ่มคำตอบให้กับคำถามของฉัน
--- อัปเดต 2 ----
ฉันพบว่า Alan Kay ตอบคำถาม"อะไรคือคุณลักษณะห้าประการของกระบวนทัศน์เชิงวัตถุที่คุณคิดว่ามีความสำคัญสำหรับแนวทางปฏิบัติด้านวิศวกรรมซอฟต์แวร์ที่ดี ” ด้วยคำพูดเหล่านี้ ในความคิดของฉัน สะท้อนกับคำตอบที่บัฟฟี่ให้ไว้ แต่วิธีการถ่ายทอดความคิดเหล่านี้ให้กับนักเรียนมัธยมปลายหรือโปรแกรมเมอร์ที่ไม่มีประสบการณ์นั้นเป็นความท้าทายอีกประการหนึ่ง
โครงสร้าง "ส่วนหนึ่ง" ที่สามารถป้องกันภายในจากภายนอก และในทางกลับกัน
โครงสร้าง "การสื่อสาร" ที่สามารถถ่ายทอดปฏิสัมพันธ์และจัดการกับการพึ่งพาได้
โครงสร้าง "ระบบ" ที่เป็นการผสมผสานระหว่างส่วนต่างๆ และการสื่อสารที่เข้ากันได้เป็นส่วนๆ แบบเรียกซ้ำ และทุกอย่างถูกสร้างในลักษณะนี้
“ข้อความ” ที่สื่อสารกันก็ในแง่ของระบบ
ระบบที่กำลังทำอยู่นั้นใช้ระบบชนิดเดียวกัน ...
คำตอบ
ฉันคาดว่าจะอัปเดตสองสามครั้งและหวังว่าจะได้คำตอบที่ยาวที่สุด
แต่ขอเริ่มด้วยการอธิบายบางสิ่งที่คุณอาจทราบแล้ว แต่ผู้อ่านคนอื่นๆ อาจไม่ทราบ
ประการแรก การเขียนโปรแกรม OO ไม่ได้เกี่ยวกับมรดก โดยพื้นฐานแล้ว หนังสือและผู้แต่งจำนวนมากเกินไปไม่เข้าใจสิ่งนั้น ยิ่งไปกว่านั้น พวกเขาใช้การสืบทอดในลักษณะที่น่ากลัวซึ่งทำให้ซอฟต์แวร์เข้าใจยากและดูแลรักษายากขึ้น
ตัวอย่างเช่น โปรดทราบว่าลำดับชั้นของรูปแบบ Linnaeus ของโลกทางชีววิทยานั้นเกือบทั้งหมดเป็น "ส่วนต่อประสาน" และไม่ใช่ "ชั้นเรียนที่เป็นนามธรรม" ซึ่งเป็นชั้นเรียนที่เป็นรูปธรรมน้อยกว่ามาก ไม่มี "สัตว์เลี้ยงลูกด้วยนม" ที่ยกตัวอย่างเช่น มันเป็นเพียงการลาจากลำดับชั้นที่สิ่งต่าง ๆ มีอยู่จริง นอกเหนือไปจากความคิด แน่นอนว่ามีความต่อเนื่องทางพันธุกรรมอยู่บ้าง
ประการที่สอง มีหลักการบางอย่างที่สามารถแนะนำคุณในการเขียนและสอนการออกแบบ OO แต่ต้องมีวินัย และส่วนหนึ่งของวินัยนั้นคือการควบคุมสถานการณ์ที่คุณ "แหก" กฎ
คำแนะนำแรกของฉันสำหรับทุกคนที่ต้องการเป็นโปรแกรมเมอร์ OO ไม่ใช่การคิดในแง่ของการสืบทอด แต่เป็นองค์ประกอบ สิ่งที่ซับซ้อน (วัตถุ) ประกอบด้วยสิ่งอื่น (วัตถุ) ที่ง่ายกว่าวัตถุที่มีอยู่เล็กน้อยและให้บริการที่จำเป็นบางอย่าง หากคุณเขียนคลาสโดยที่ตัวแปรอินสแตนซ์ทั้งหมด (หรือเกือบทั้งหมด) เป็นภาษาพื้นฐาน คุณจะไม่เข้าใจมันจริงๆ และหากตัวแปรอินสแตนซ์เหล่านั้น (อ็อบเจ็กต์หรือดั้งเดิม) มีตัวรับและตัวตั้งค่าจำนวนมาก แสดงว่าคุณไม่ได้ทำการเขียนโปรแกรม OO เลย
อันที่จริง การทำผิดพลาดข้างต้น ต้องการให้โปรแกรมเมอร์ติดตามรายละเอียดทั้งหมดในทุกจุดของโปรแกรมที่ OO ได้รับการออกแบบมาเพื่อจับภาพการตัดสินใจเพื่อไม่ให้ "ตรวจสอบ" อีกครั้ง ตั้งค่าและลืมมันเพื่อที่จะพูด
ดังนั้น หากคุณต้องการสร้างรถยนต์ อย่าคิดว่ามันเป็นซับคลาสของยานพาหนะ (ซึ่งไม่ได้ประโยชน์อะไรจากคุณเลย: โดรนส่วนตัวและเรือรบเป็นพาหนะทั้งสองคัน) ให้คิดว่าแทนที่จะประกอบด้วยชิ้นส่วนต่างๆ: เครื่องยนต์ เกียร์ ระบบควบคุม ที่พัก ฯลฯ และส่วนเหล่านั้นเอง ประกอบด้วยชิ้นส่วน เครื่องยนต์มีเครื่องจุดไฟและลูกสูบ ท่อไอเสีย ฯลฯ ซึ่งส่วนใหญ่ประกอบด้วยชิ้นส่วนต่างๆ ด้วย มันเป็นเพียงระดับต่ำสุด ง่ายที่สุดที่คุณสร้างด้วยพื้นฐาน
สองหลักการที่มีมูลค่าการรักษาในใจและต่อไปนี้มักจะเป็นLiskov ชดเชยหลักการและกฎหมายของ Demeter
ข้อแรกแนะนำว่าถ้าคุณขยายคลาสด้วยคลาสย่อย คุณจะไม่ขยายส่วนต่อประสานสาธารณะของคลาสย่อยด้วย จากนั้นอ็อบเจ็กต์คลาสย่อยทั้งหมดจะแทนที่ได้ โดยมีลักษณะการทำงานต่างกันแต่ไม่อยู่ในอินเทอร์เฟซ ในทางกลับกัน Demeter บังคับให้คุณเขียนโค้ดที่ชัดเจนขึ้นซึ่งทำให้ความสัมพันธ์ชัดเจนต่อผู้อ่าน แน่นอนว่ามันยังบังคับให้คุณแนะนำชื่อเพิ่มเติม และหากพวกเขาตั้งใจที่จะเปิดเผยชื่อรหัสของคุณก็จะชัดเจนขึ้น
แน่นอนว่าหลักการของ Liskov เป็นหนึ่งในองค์ประกอบของSOLIDที่คุณต้องรวมเข้ากับความคิดของคุณด้วย
ในการเขียนโปรแกรมของฉันเอง ฉันซื่อสัตย์ต่อ Liskov มาก และยังกำหนดอินเทอร์เฟซสำหรับสิ่งต่างๆ ส่วนใหญ่ก่อนที่จะเขียนคลาส ฉันไม่ค่อยซื่อสัตย์ต่อ Demeter ในการต่อสู้ที่ดุเดือด ข้อความเรียงซ้อน แต่แล้วบางครั้งฉันก็จำเป็นต้องคลี่คลายการเรียงซ้อน abcd เหล่านั้นเพื่อค้นหาว่าฉันหมายถึงอะไรจริงๆ
เป้าหมายหนึ่งที่ฉันมีในการเขียนโค้ด OO คือพยายามเขียนเฉพาะวิธีที่สั้นมากด้วยโครงสร้างขั้นต่ำ ในคำอื่น ๆ ที่ฉันพยายามที่จะลดCyclomatic ซับซ้อนฝ่ามือของฉันเริ่มคันหลังจากคำสั่งที่สี่ในวิธีใดวิธีหนึ่งหรือหากระดับความซับซ้อนถึงสาม ฉันไม่สามารถหลีกเลี่ยงสิ่งนั้นได้ตลอดเวลา แต่มันคือเป้าหมาย การแก้ปัญหาคือการปรับโครงสร้างความซับซ้อนใหม่อย่างไร้ความปราณี แน่นอนแยกปัจจัยออก แต่ยังรวมถึง "ชิ้นส่วน" สร้างคลาสใหม่เพื่อจัดการความซับซ้อน แม้ว่าคลาสเหล่านั้นจำนวนมากจะเป็นซิงเกิลตัน แต่โค้ดมักจะได้รับการปรับปรุงและมีเป้าหมายในใจตั้งแต่เริ่มต้น หมายความว่าขั้นตอนการรีแฟคเตอร์นั้นไม่จำเป็น
รูปแบบการออกแบบเป็นเครื่องมือที่คุณต้องเป็นโปรแกรมเมอร์ที่มีประสิทธิภาพในภาษา OO ส่วนใหญ่ สิ่งที่เป็นประโยชน์อย่างยิ่ง ได้แก่ กลยุทธ์ มัณฑนากร ผู้สังเกตการณ์ และตัววนซ้ำ ส่วนใหญ่จะใช้เพื่อสร้างไลบรารี Java ต่างๆ
ทีนี้มาที่คำถามจริงที่ถามกันที่นี่ แต่โปรดทราบว่าการเรียนรู้จำนวนมากสามารถเกิดขึ้นได้แม้ว่านักเรียนจะไม่มีวันทำโครงงานจนเสร็จภายในเวลาที่กำหนด แนวทางที่คล่องตัว (Extreme Programming สมมติว่าคุณเป็น "ลูกค้า") ในการพัฒนาทำให้พวกเขามีฟังก์ชันการทำงานบางอย่างแม้ว่าจะไม่ได้ใช้งานข้อกำหนดทั้งหมดก็ตาม
เกมดันเจี้ยน
สร้างเกมดันเจี้ยนข้อความ วัตถุหลักคือตัวละคร (คน) สถานที่และสิ่งของ สถานที่จัดอยู่ในแผนที่ เขาวงกต หรือตารางบางประเภท สิ่งต่าง ๆ เกิดขึ้นเมื่อตัวละครเข้าสู่สถานที่ ตัวละครค้นหาและพกพาสิ่งของต่างๆ สิ่งของมีการกระทำขึ้นอยู่กับชนิดของสิ่งของ "คาถา" เป็น "สิ่งของ" ซึ่งการกระทำอาจขึ้นอยู่กับบริบท วัตถุ "ผู้ขนส่ง" อาจทำงานแตกต่างกันในห้องต่างๆ (วัตถุกลยุทธ์)
โปรดทราบว่าเกมกระดานคลาสสิกChutes (หรือ Snakes) and Laddersเป็นเวอร์ชันที่เรียบง่าย เวอร์ชันที่ใช้ข้อความช่วยหลีกเลี่ยงความซับซ้อนมากมาย
เครื่องคิดเลข
เครื่องคิดเลขมีส่วนต่างๆ เช่น กุญแจและจอแสดงผล หน่วยความจำภายในที่มองเห็นได้น้อยลงอาจเป็นสแต็ก แม้แต่การดำเนินการก็สามารถเป็นวัตถุได้ ลักษณะการทำงานของปุ่มจะเปลี่ยนไป ขึ้นอยู่กับสถานะของการคำนวณ (รูปแบบกลยุทธ์) เป็นไปได้ที่จะสร้างเครื่องคิดเลขแบบง่ายๆ โดยไม่ต้องใช้คำสั่ง IF แม้แต่คำสั่งเดียว
คอมพิวเตอร์นามธรรมกับภาษาแอสเซมบลี
การจำลองตัวประมวลผลคอมพิวเตอร์แบบ Stack Based นั้นค่อนข้างตรงไปตรงมา อาจมีตัวสะสมและอื่น ๆ แต่สแต็กเดียวที่การดำเนินการทั้งหมดเสร็จสิ้นนั้นง่ายและสมบูรณ์ การดำเนินการสามารถเป็นวัตถุ (บางส่วน) ข้อดีอย่างหนึ่งของตัวอย่างนี้คือวิธีการที่จำเป็นส่วนใหญ่อาจสั้นมาก สามารถอ่านโปรแกรมด้วยวัตถุ Java Scanner อย่างน้อยต้องมีตัวนับโปรแกรมและอาจเป็นตัวชี้เฟรมหากภาษานั้นรองรับรูทีนย่อย
Sticky Notes (ฉันยังไม่ได้ลอง)
แอปพลิเคชันที่ช่วยให้ผู้ใช้จดบันทึกและอ้างอิงโยงและจัดระเบียบได้ บางคลาสอาจเป็น Notes, Keywords, Connections, Lists
อันตราย
เกมจำลองสถานการณ์อันตรายจากทีวี หมวดหมู่ คำตอบ คำถาม ทีม คะแนน
(กลับมาเร็ว ๆ นี้อาจจะ)
ฉันพบว่าคลาส Python นั้นง่ายต่อการเขียน (สำหรับงาน "ทางโลก") ที่พวกเขาสามารถเติบโตตามธรรมชาติจากความปรารถนาที่จะทำให้ง่ายขึ้นและปรับโครงสร้างโค้ดในการพัฒนา เป็นแนวทางจากล่างขึ้นบนในทางปฏิบัติอย่างมาก คุณคาดหวังที่จะแฮ็คโค้ดง่ายๆ สำหรับวัตถุประสงค์เฉพาะ จากนั้นมันก็เพิ่มขึ้นอีกเล็กน้อย และคุณพบว่าคุณมีฟังก์ชันหลายอย่างในการจัดการ "โครงสร้าง" ที่เป็น tuples หรืออาร์เรย์ หรือแม้แต่ globals ทันใดนั้น คุณเห็นแสงสว่างและสร้างคลาส และขนาดโค้ดถูกหารด้วย 2 หรือมากกว่านั้น และง่ายกว่ามาก
นี่เป็นวิธีง่ายๆ ในการโต้แย้ง OOP โดยนำโค้ดที่มีอยู่ "แบน" ที่เป็นรูปธรรมและมองหาสิ่งที่เป็นนามธรรมที่สามารถทำได้ ย้ายข้อมูลออกจากพารามิเตอร์ของฟังก์ชัน ไปยังคลาส และใช้self
.
สิ่งต่าง ๆ เช่นมรดกสามารถค้นพบได้เกือบเป็นธรรมชาติในทำนองเดียวกัน คุณใช้คลาสที่มีอยู่ซึ่งไม่ค่อยทำในสิ่งที่คุณต้องการและคุณจำเป็นต้องเปลี่ยน แทนที่จะคัดลอกและแก้ไข คุณเปลี่ยนหรือเพิ่มเมธอด
สำหรับตัวอย่างที่เป็นรูปธรรม คุณสามารถดูฮาร์ดแวร์ของคอมพิวเตอร์เองได้ ในระดับต่ำ รีจิสเตอร์มักจะถูกแบ่งแยกออกเป็นหลายฟังก์ชันที่แตกต่างกัน หากคุณต้องการตั้งค่าบิตคุณลักษณะเป็น 1 คุณต้องเลื่อนไปทางซ้าย 20 บิต อ่านค่าปัจจุบันของรีจิสเตอร์ ปิดบังบิต 0 ถึง 5 เนื่องจากเป็น "เขียน 1 เพื่อล้าง" เป็นต้น ลองจำลองพอร์ตอนุกรม 16550 uart; มันเป็นสิ่งที่ดีสำหรับจิตวิญญาณ และแน่นอน ถ้าคุณใช้ MicroPython ที่ทำงานบนไมโครโปรเซสเซอร์จริง คุณอาจจะลองใช้โค้ดของคุณด้วยซ้ำ
ฉันไปเพื่อเป็นตัวอย่างสำหรับการสร้างแบบจำลองทั้งข้อมูลและ OOP (ซึ่งในทั้งสองกรณีหมุนรอบชนิดของการฟื้นฟูก) เป็นร้านเช่าวิดีโอ อาจเป็นตัวอย่างที่ล้าสมัย อย่าลังเลที่จะเปลี่ยนเป็นห้องสมุดหรือร้านเช่าสำหรับสิ่งอื่น ๆ แต่ฉันพบว่าตัวอย่างที่เก็บวิดีโอทั้งสองเน้นถึงความซับซ้อนของ OOP และการปรับข้อมูลให้เป็นมาตรฐาน ในขณะเดียวกันก็ง่ายมาก บริบทที่จะเข้าใจ
เป้าหมายหลักคือการสร้างถึงสามตาราง / แผนภาพคลาส: Customer
, Video
และRental
(ซึ่งเป็นตารางข้ามระหว่างลูกค้าและวิดีโอ)
ส่วนที่เหลือของคำตอบนี้เป็นเพียงคำแนะนำเกี่ยวกับวิธีเชื่อมโยงข้อมูลพื้นฐาน OOP เฉพาะกับตัวอย่างที่อยู่ในมือ
ทำไมต้องวัตถุ?
คุณจะจัดเก็บข้อมูลวิดีโอของคุณอย่างไร หากคุณต้องการติดตามสามสิ่งสำหรับการเช่า: ชื่อลูกค้า ที่อยู่ ชื่อวิดีโอ และวันที่คาดว่าจะส่งคืน
ขอให้นักเรียนเขียนโปรแกรมง่ายๆ ที่สามารถบอกคุณได้ว่า Alice เช่า Antz, Bob เช่า Bee Movie และ Charlie เช่ารถ ปล่อยให้พวกเขาพึ่งพาPrintRentalInfo
วิธีการที่ใช้ซ้ำได้แต่ให้พวกเขากำหนดพารามิเตอร์ของวิธีการตามที่เห็นสมควร
นักเรียนที่ยังไม่ได้ดู OOP จะใช้อาร์เรย์ที่แตกต่างกันสี่ชุด และอาศัยข้อเท็จจริงที่ว่ามีวิดีโอหนึ่งรายการอยู่ในดัชนีเดียวกันในอาร์เรย์ทั้งสี่ อธิบายให้พวกเขาฟังว่าแทนที่จะมี "กระเป๋า" ของชื่อลูกค้า "กระเป๋า" ที่อยู่ "กระเป๋า" ชื่อวิดีโอ และ "กระเป๋า" ของวันที่ส่งคืนนั้นไม่ใช่เรื่องง่ายเลย เสนอแนวคิดที่ว่า แทนที่จะทำ "กระเป๋า" ต่อช่องข้อมูล มันจะดีกว่าถ้าเราทำ "กระเป๋า" ต่อการเช่า
สร้างRental
คลาสด้วยคุณสมบัติสี่ประการ สร้างแอปพลิเคชันเดียวกับที่ทำ แต่ใช้ OOP สิ่งนี้จะแสดงให้พวกเขาเห็นว่าการกำหนดค่าเริ่มต้นของออบเจ็กต์ วิธีการที่อ็อบเจ็กต์ต่างกันมีโครงสร้างเดียวกันแต่เป็นเนื้อหาที่ไม่ซ้ำกัน และวิธีที่คุณสามารถส่งผ่านอ็อบเจ็กต์ไปรอบๆ (ซึ่งต่างจากพารามิเตอร์เมธอดหลายรายการของประเภทดั้งเดิม)
เน้นจริงๆ ว่าคุณสามารถย้าย "กระเป๋า" ที่เช่านี้ได้ง่ายเพียงใดจากวิธีหนึ่งไปอีกวิธีหนึ่ง โดยเก็บข้อมูลที่เกี่ยวข้องทั้งหมดไว้ด้วยกัน
ทำไมมากกว่าหนึ่งชั้นเรียน?
ลูกค้ารายที่สี่ปรากฏขึ้น เธอชื่ออลิซเช่นกัน คุณประสบปัญหาที่นี่ เพราะตอนนี้คุณไม่สามารถบอกได้ว่าอลิซเช่าวิดีโอใด และคุณไม่ต้องการที่จะปรับอลิซผิด
นอกจากนี้ อลิซคนเดิมได้โทรหาเราเพื่อแจ้งให้เราทราบว่าที่อยู่ของเธอเปลี่ยนไป ชี้ให้เห็นถึงความยากลำบากในการต้องผ่านการเช่าทั้งหมดและพบว่าคุณไม่สามารถเปลี่ยน "old_address" เป็น "new_address" อย่างสุ่มสี่สุ่มห้าได้ เพราะอาจมีลูกค้ารายอื่นที่อาศัยอยู่ในที่อยู่เดียวกันนั้นที่ไม่ได้ย้ายกับอลิซ นอกจากนี้ คุณไม่สามารถพึ่งพาชื่อได้เช่นกัน เนื่องจากอลิซคนที่สี่ได้เช่าไปแล้วด้วย
หากนักเรียนยังคงประท้วงว่าคุณทำได้โดยใช้ชื่อและที่อยู่ร่วมกัน เหมือนกับว่าเกิดอะไรขึ้นถ้าอลิซสองคนนั้นอาศัยอยู่ที่เดียวกัน และมีเพียงคนเดียวเท่านั้นที่เคลื่อนไหว
แนะนำนักเรียนว่า คงจะสมเหตุสมผลมากถ้าเรามีรายชื่อลูกค้าทั้งหมดและที่อยู่ของลูกค้าแยกจากกัน เพื่อให้เราสามารถแยกความแตกต่างได้มากกว่าแค่ชื่อของพวกเขา และเปลี่ยนรายละเอียดของคนเดียวได้อย่างง่ายดาย
เป้าหมาย: สร้างCustomer
คลาสและเปลี่ยนแปลงRental
เพื่อให้รวมCustomer
พร็อพเพอร์ตี้ที่ตรงข้ามกับคุณสมบัติชื่อ/ที่อยู่
โฟกัส: ไฮไลท์มากวิธีการที่คุณสามารถมีสองที่แตกต่างกันวัตถุลูกค้าแม้เมื่อชื่อและที่อยู่ของพวกเขาเหมือนกัน
พิเศษ: คุณสามารถใช้แนวทางเดียวกันในการสร้างVideo
ชั้นเรียน เพื่อให้คุณสามารถติดตามวิดีโอเฉพาะที่คุณมี อาจจะปล่อยให้เป็นแบบฝึกหัดสำหรับนักเรียน เพราะมันก็เหมือนเมื่อก่อนมาก
จากจุดนี้ไป คุณสามารถขยายตรรกะทางธุรกิจตามสิ่งที่คุณต้องการแสดง
- การสืบทอด - บางทีร้านอาจเช่า
Video
และGame
แต่คุณยังต้องการRental
ลิงก์ไปยังร้านใดร้านหนึ่ง (โดยใช้RentableObject
คลาสพื้นฐาน) - ส่วนต่อประสาน - คุณสามารถใช้ตัวอย่างเดียวกันกับการสืบทอด
- การปรับข้อมูลให้เป็นมาตรฐาน - เราจะดำเนินการอย่างไรในการติดตามภาพยนตร์ที่เรามีอยู่ และตลับเทปจริง (เราสามารถมีภาพยนตร์เดียวกันได้หลายเรื่อง) จะสามารถติดตามค่าปรับที่เกิดขึ้นกับลูกค้าได้อย่างไร และค่าปรับใดที่พวกเขาได้ชำระไปแล้ว?
- การแปลงข้อมูล - หัวหน้าของเราต้องการให้เราพิมพ์รายงานรายสัปดาห์เกี่ยวกับการเช่าทั้งหมด การคืนค่าเช่า ค่าปรับที่เกิดขึ้น และค่าปรับจากก่อนหน้านี้ที่ยังไม่ได้ชำระ
- Reference vs value - เพิ่ม a
Price
ให้กับทั้งVideo
และRental
. แสดงวิธีการตั้งค่าของคุณrental.Price
ตามvideo.Price
แต่เมื่อมีvideo.Price
การเปลี่ยนแปลงในภายหลังrental.Price
จะไม่ถูกแตะต้อง ทำซ้ำแบบฝึกหัดเดิมด้วยวัตถุอ้างอิง (เช่น การเปลี่ยนชื่อลูกค้า)
ฉันพบว่าบริบทของตัวอย่างนี้เข้าใจได้ง่าย และมีโอกาสมากมายสำหรับการขยาย สิ่งนี้สามารถเติบโตเป็นโครงการระยะยาวที่คุณขยายต่อไป ซึ่งอาจเป็นบทเรียนที่มีค่าหากคุณต้องการสอนนักเรียนของคุณเกี่ยวกับวิธีจัดการกับความต้องการที่เปลี่ยนแปลงไปและประโยชน์ของการเขียนโค้ดที่สะอาด หรือการบำรุงรักษาและการพัฒนาแบบเดิม