ฟังก์ชั่นที่บริสุทธิ์เทียบกับบอกไม่ต้องถาม?


14

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

( ที่มา: ความเห็นโดย @David Arno ภายใต้คำถามอื่นบนเว็บไซต์นี้ )

ความคิดเห็นที่ได้รับเพิ่มขึ้นอย่างน่าทึ่งจาก 133 upvotes ซึ่งเป็นเหตุผลที่ฉันต้องการที่จะให้ความสนใจอย่างใกล้ชิดกับบุญของมัน

เท่าที่ฉันทราบมีสองวิธีในการเขียนโปรแกรม: การเขียนโปรแกรมการทำงานที่บริสุทธิ์ (สิ่งที่ความคิดเห็นนี้เป็นกำลังใจ) และบอกอย่าถาม (ซึ่งเป็นครั้งคราวแนะนำบนเว็บไซต์นี้เช่นกัน) AFAIK หลักการสองข้อนี้ไม่สามารถใช้ร่วมกันได้ใกล้เคียงกับสิ่งที่ตรงกันข้าม: การทำงานที่บริสุทธิ์สามารถสรุปได้ว่า "เพียงแค่คืนค่าไม่มีผลข้างเคียง" ในขณะที่บอกอย่าถามสามารถสรุปได้ว่า "ไม่คืนสิ่งใดเลย" มีผลข้างเคียงเท่านั้น " นอกจากนี้ฉันยังงุนงงเพราะฉันคิดว่าการบอกอย่าถามถือเป็นแกนหลักของกระบวนทัศน์ OO ในขณะที่ funcitons บริสุทธิ์ถือเป็นแกนหลักของกระบวนทัศน์การทำงาน - ตอนนี้ฉันเห็นฟังก์ชั่นบริสุทธิ์ที่แนะนำใน OO!

ฉันคิดว่านักพัฒนาน่าจะเลือกหนึ่งในกระบวนทัศน์เหล่านี้และยึดติดกับมัน? ฉันต้องยอมรับว่าฉันไม่สามารถพาตัวเองไปติดตามได้ บ่อยครั้งที่มันสะดวกสำหรับฉันที่จะคืนค่าและฉันไม่สามารถมองเห็นได้ว่าฉันจะบรรลุสิ่งที่ฉันต้องการเพื่อให้บรรลุเฉพาะกับผลข้างเคียง บ่อยครั้งที่มันสะดวกสำหรับฉันที่จะมีผลข้างเคียงและฉันไม่เห็นจริง ๆ ว่าฉันจะบรรลุสิ่งที่ฉันต้องการได้รับเพียงแค่คืนค่า นอกจากนี้บ่อยครั้ง (ฉันเดาว่ามันน่ากลัว) ฉันมีวิธีการที่ทำทั้งสองอย่าง

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

ดังนั้นในตัวอย่างของเกมขี่ม้า antipattern นี้ฉันพยายามทำ : ถ้าฉันต้องการที่จะนำมันไปใช้กับกระบวนทัศน์การทำงานที่บริสุทธิ์ - อย่างไร!

ดูเหมือนว่าฉันมีเหตุผลที่จะมีสถานะการต่อสู้ เนื่องจากเกมนี้เป็นเกมเทิร์นเบสฉันจึงรักษาสถานะการต่อสู้ไว้ในพจนานุกรม (ผู้เล่นหลายคน - อาจมีการต่อสู้จำนวนมากที่ผู้เล่นหลายคนเล่นพร้อมกัน) เมื่อใดก็ตามที่ผู้เล่นหันมาฉันเรียกวิธีการที่เหมาะสมในสถานะการต่อสู้ซึ่ง (a) แก้ไขสถานะตามนั้นและ (b) คืนการอัปเดตให้กับผู้เล่นซึ่งได้รับการต่อเนื่องเป็น JSON และบอกพวกเขาว่าเกิดอะไรขึ้น คณะกรรมการ. ฉันคิดว่านี่เป็นการละเมิดหลักการทั้งสองอย่างชัดแจ้งและในเวลาเดียวกัน

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

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

ดูเหมือนว่าฉันจะปรับเปลี่ยนสถานะได้ง่ายกว่าและง่ายกว่ามาก ...

แต่วิศวกรที่มีประสบการณ์จะรับมือกับสิ่งนี้ได้อย่างไร


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

1
ฉันไม่เคยมีคำถามถามที่นี่เกี่ยวกับสิ่งที่ฉันเคยพูดมาก่อน ฉันรู้สึกเป็นเกียรติ :)
David Arno

คำตอบ:


14

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

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

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


ขอบคุณที่อธิบาย "บอกอย่าถาม" อย่างถูกต้อง
user949300

13

ทั้งลุงบ๊อบและเดวิดอาร์โน (ผู้เขียนคำพูดของคุณ) มีบทเรียนสำคัญที่เราสามารถรวบรวมได้จากสิ่งที่พวกเขาเขียน ฉันคิดว่ามันคุ้มค่าที่จะเรียนรู้บทเรียนจากนั้นประเมินสิ่งที่มีความหมายสำหรับคุณและโครงการของคุณ

ครั้งแรก: บทเรียนของลุงบ็อบ

ลุงบ๊อบชี้ให้เห็นว่ายิ่งคุณมีข้อโต้แย้งมากขึ้นในการทำงาน / วิธีการของคุณมากขึ้นนักพัฒนาที่ใช้มันต้องเข้าใจ ภาระการรับรู้นั้นไม่ได้มาฟรีและถ้าคุณไม่สอดคล้องกับคำสั่งของข้อโต้แย้ง ฯลฯ ภาระการรับรู้จะเพิ่มขึ้นเท่านั้น

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

ดังที่อัลเบิร์ตไอน์สไตน์กล่าวว่า“ ทุกสิ่งควรเรียบง่ายเท่าที่จะทำได้ แต่ไม่ง่ายกว่า”

ประการที่สอง: บทเรียนของ David Arno

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

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

การพัฒนาเป็นชุดของการแลกเปลี่ยน

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

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

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

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


มีอัมพาตอยู่ การต่อสู้ที่แตกต่างกันสามารถดำเนินการในแบบคู่ขนาน อย่างไรก็ตามใช่: การต่อสู้เดียวในขณะที่มันกำลังถูกประมวลผลจำเป็นต้องถูกล็อค
gaazkam

ใช่ฉันหมายความว่าผู้อ่าน (เกี่ยวในการเปรียบเทียบของคุณ) จะรวบรวมจากงานเขียนของพวกเขา ที่กล่าวว่าฉันได้กลับไปดูบางสิ่งที่ฉันเขียนในอดีตและได้ relearned บางสิ่งบางอย่างหรือไม่เห็นด้วยกับตัวเองในอดีตของฉัน เราทุกคนกำลังเรียนรู้และพัฒนาและนั่นคือเหตุผลอันดับหนึ่งว่าทำไมคุณควรให้เหตุผลเสมอว่าคุณจะนำสิ่งที่เรียนรู้ไปใช้อย่างไรและอย่างไร
Berin Loritsch

8

ตกลง - ฉันสามารถสร้างวิธีการคืนค่าสถานะการต่อสู้แทนการปรับเปลี่ยนได้ถ้าฉันต้องการ

ใช่นั่นคือความคิด

จากนั้นฉันจะต้องคัดลอกทุกอย่างในสถานะการต่อสู้เพื่อกลับสู่สถานะใหม่ทั้งหมดแทนที่จะแก้ไขในสถานที่หรือไม่?

ไม่ได้ "สถานะการต่อสู้" ของคุณอาจถูกจำลองเป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปซึ่งมีโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปแบบเป็นแบบเอกสารสำเร็จรูปซึ่งอาจซ้อนอยู่ในลำดับชั้นของโครงสร้างข้อมูลที่เปลี่ยนแปลงไม่ได้

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

Google สำหรับ "โครงสร้างข้อมูลที่ไม่เปลี่ยนรูปแบบได้อย่างมีประสิทธิภาพ" และคุณจะพบการอ้างอิงบางอย่างเกี่ยวกับวิธีการทำงานโดยทั่วไป

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

สำหรับปัญหาบางอย่างสิ่งนี้อาจง่ายกว่านี้จริงๆ เกมและการจำลองรอบอาจตกอยู่ภายใต้หมวดหมู่นี้เนื่องจากสถานะส่วนใหญ่ของเกมเปลี่ยนจากรอบหนึ่งเป็นอีกรอบ อย่างไรก็ตามการรับรู้ของสิ่งที่ "เรียบง่าย" จริง ๆ ก็คือในระดับส่วนตัวและมันก็ขึ้นอยู่กับสิ่งที่ผู้คนคุ้นเคย


8

ในฐานะผู้เขียนความคิดเห็นฉันคิดว่าฉันควรอธิบายให้ชัดเจนที่นี่เพราะแน่นอนว่ามีมากกว่านั้นในเวอร์ชันที่ง่ายกว่าที่ความคิดเห็นของฉันมีให้

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

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

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

ลองย้อนกลับไปสู่จุดเริ่มต้นที่เรียบง่าย เรามี "ก้อนของตรรกะ" (ขั้นตอน) และเรามีข้อมูลทั่วโลก ขั้นตอนการอ่านข้อมูลนั้นโดยตรงเพื่อเข้าถึง เรามีสถานการณ์ "ถาม" ง่าย ๆ

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

ดังนั้นจบการทำงานในยุคปัจจุบันทิ้งแนวทาง "ของ OO ไปจนสุด" แล้วยืมหลักการบางอย่างจากการเขียนโปรแกรมที่ใช้งานได้ ตอนนี้เมื่อมีการเรียกเมธอดข้อมูลทั้งหมดจะถูกส่งไปยังพารามิเตอร์ของมัน มันสามารถ (และมี) ที่ถกเถียงกันว่า "ประเด็นคืออะไรมันซับซ้อนแค่โค้ดเหรอ?" และใช่การส่งผ่านพารามิเตอร์ข้อมูลที่เข้าถึงได้ผ่านขอบเขตของวัตถุจะเพิ่มความซับซ้อนให้กับรหัส แต่การจัดเก็บข้อมูลนั้นในวัตถุแทนที่จะทำให้สามารถเข้าถึงได้ทั่วโลกจะเพิ่มความซับซ้อนด้วย แต่น้อยคนนักที่จะเถียงว่าตัวแปรทั่วโลกดีกว่าเสมอเพราะมันง่ายกว่า ประเด็นก็คือประโยชน์ที่ "บอกไม่ต้องถาม" นำมาเทียบกับความซับซ้อนของการลดขอบเขต สิ่งนี้ใช้มากขึ้นในการส่งผ่านพารามิเตอร์มากกว่าการ จำกัด ขอบเขตของวัตถุprivate staticและผ่านทุกสิ่งที่มันต้องการผ่านพารามิเตอร์และตอนนี้วิธีการนั้นสามารถไว้วางใจได้ที่จะไม่แอบเข้าไปในสิ่งที่มันไม่ควร นอกจากนี้ยังเป็นการสนับสนุนให้วิธีการมีขนาดเล็กมิฉะนั้นรายการพารามิเตอร์ที่ได้รับจากมือ และมันสนับสนุนวิธีการเขียนที่ตรงกับเกณฑ์ "ฟังก์ชั่นบริสุทธิ์"

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

แต่สิ่งสำคัญที่ต้องจำไว้ว่า "การดำเนินการบอกไม่ต้องถาม" อย่างแท้จริงนั้นเป็นอุดมคติเช่นลัทธิปฏิบัตินิยมต้องเข้ามาเล่นน้อยกว่าเราจะกลายเป็นอุดมคติและจึงปฏิบัติต่อมันอย่างผิด ๆ มีแอปน้อยมากที่สามารถใกล้เคียงกับผลข้างเคียงได้ฟรี 100% ด้วยเหตุผลง่ายๆว่าพวกเขาไม่ได้ทำอะไรที่มีประโยชน์หากพวกเขาปราศจากผลข้างเคียงอย่างแท้จริง เราต้องการการเปลี่ยนสถานะเราต้องการ IO และอื่น ๆ เพื่อให้แอปมีประโยชน์ และในกรณีเช่นนี้วิธีการต้องก่อให้เกิดผลข้างเคียงและต้องไม่บริสุทธิ์ แต่กฎของหัวแม่มือที่นี่คือการทำให้วิธี "ไม่บริสุทธิ์" เหล่านี้ให้น้อยที่สุด; พวกเขามีผลข้างเคียงเพียงเพราะพวกเขาต้องการมากกว่าปกติ

ดูเหมือนว่าฉันมีเหตุผลที่จะมีสถานะการต่อสู้ เนื่องจากเกมนี้เป็นเกมเทิร์นเบสฉันจึงรักษาสถานะการต่อสู้ไว้ในพจนานุกรม (ผู้เล่นหลายคน - อาจมีการต่อสู้จำนวนมากที่ผู้เล่นหลายคนเล่นพร้อมกัน) เมื่อใดก็ตามที่ผู้เล่นหันมาฉันเรียกวิธีการที่เหมาะสมในสถานะการต่อสู้ซึ่ง (a) แก้ไขสถานะตามนั้นและ (b) คืนการอัปเดตให้กับผู้เล่นซึ่งได้รับการต่อเนื่องเป็น JSON และบอกพวกเขาว่าเกิดอะไรขึ้น คณะกรรมการ.

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

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

และเป็นจุดสุดท้ายเพียงเพื่อย้ำ: ฟังก์ชั่นที่บริสุทธิ์และ "บอกไม่ต้องถาม" จะไม่ตรงข้ามเลย


5

สำหรับทุกสิ่งที่เคยพูดมีบริบทที่คุณสามารถใส่คำสั่งที่จะทำให้มันไร้สาระ

ป้อนคำอธิบายรูปภาพที่นี่

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

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

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

ฉันสามารถทำให้สิ่งที่เปลี่ยนไม่ได้และผลข้างเคียงฟรีในสไตล์ OOP อย่างสมบูรณ์ Return เป็นเพียงกลไกที่ใช้เก็บค่าไว้ใน stack สำหรับขั้นตอนต่อไป คุณสามารถอยู่เฉยๆได้โดยใช้พอร์ตเอาต์พุตเพื่อสื่อสารค่ากับสิ่งที่ไม่เปลี่ยนรูปแบบอื่น ๆ จนกว่าคุณจะกดพอร์ตสุดท้ายที่ต้องเปลี่ยนบางอย่างถ้าคุณต้องการให้ผู้คนสามารถอ่านได้ นั่นเป็นเรื่องจริงสำหรับทุกภาษาหน้าที่หรือไม่

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

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

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

นี่ไม่ใช่ปัญหาใหม่ เป็นเวลาหลายปีที่ผู้คนเขียนโค้ดแบบขั้นตอนใน "ภาษา OO" คิดว่าพวกเขากำลังทำ OO เพราะพวกเขาใช้ "ภาษา OO" มีภาษาเพียงไม่กี่ภาษาที่ช่วยให้คุณไม่ต้องยิงด้วยตัวเอง สำหรับแนวคิดเหล่านี้ในการทำงานพวกเขาต้องอยู่ในตัวคุณ

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


0

บางครั้งฉันก็ต้องดิ้นรนเพื่อให้เข้าใจถึงกฎของกระบวนทัศน์ต่างๆ บางครั้งพวกเขาก็ขัดแย้งกับคนอื่นเหมือนอยู่ในสถานการณ์นี้

OOP เป็นกระบวนทัศน์ที่จำเป็นซึ่งเกี่ยวกับการวิ่งด้วยกรรไกรในโลกที่สิ่งอันตรายเกิดขึ้น

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

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

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

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

ดังนั้นเมื่อคุณเขียนวัตถุที่ไม่เปลี่ยนรูป (สิ่งที่ Clojure เรียกว่าโครงสร้างข้อมูลถาวร) โปรดจำไว้ว่าคุณอยู่ในโดเมนที่ใช้งานได้ โยนบอกอย่าถามออกไปนอกหน้าต่างแล้วปล่อยให้มันกลับเข้ามาในบ้านก็ต่อเมื่อคุณกลับเข้าสู่อาณาจักรที่จำเป็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.