ฉันจะสร้างระบบที่มีสิ่งต่อไปนี้ทั้งหมดได้อย่างไร :
- การใช้ฟังก์ชั่นบริสุทธิ์กับวัตถุที่ไม่เปลี่ยนรูป
- ส่งผ่านไปยังข้อมูลฟังก์ชันที่ฟังก์ชันต้องการเท่านั้นไม่เกิน (เช่นไม่มีวัตถุสถานะแอปพลิเคชันขนาดใหญ่)
- หลีกเลี่ยงการขัดแย้งกับฟังก์ชันมากเกินไป
- หลีกเลี่ยงการสร้างวัตถุใหม่เพียงเพื่อจุดประสงค์ในการบรรจุและเอาพารามิเตอร์ออกจากฟังก์ชั่นเพื่อหลีกเลี่ยงการส่งพารามิเตอร์ไปยังฟังก์ชันมากเกินไป ถ้าฉันจะแพ็คหลายรายการไปยังฟังก์ชันเป็นวัตถุเดียวฉันต้องการให้วัตถุนั้นเป็นเจ้าของข้อมูลนั้นไม่ใช่สิ่งที่สร้างขึ้นชั่วคราว
สำหรับฉันแล้วดูเหมือนว่ารัฐ monad ทำผิดกฎข้อที่ 2 ถึงแม้ว่ามันจะไม่ชัดเจนเพราะมันถูกสานต่อผ่าน monad
ฉันรู้สึกว่าฉันจำเป็นต้องใช้เลนส์อย่างใด แต่มีน้อยมากที่เขียนเกี่ยวกับมันสำหรับภาษาที่ไม่สามารถใช้งานได้
พื้นหลัง
ในการออกกำลังกายฉันกำลังแปลงแอปพลิเคชันที่มีอยู่ของฉันจากสไตล์เชิงวัตถุเป็นสไตล์การทำงาน สิ่งแรกที่ฉันพยายามทำคือการสร้างแกนในของแอปพลิเคชันให้ได้มากที่สุด
สิ่งหนึ่งที่ฉันได้ยินคือวิธีการจัดการ "รัฐ" ในภาษาที่ใช้งานได้อย่างหมดจดและนี่คือสิ่งที่ฉันเชื่อว่าทำโดย Monads ของรัฐนั่นคือเหตุผลที่คุณเรียกฟังก์ชันบริสุทธิ์ว่า "ผ่านสถานะของ โลกตามที่มันเป็น "จากนั้นเมื่อฟังก์ชั่นกลับมาก็จะกลับสู่สถานะของโลกตามที่มีการเปลี่ยนแปลง
เพื่อแสดงให้เห็นว่าวิธีการที่คุณสามารถทำ "สวัสดีโลก" ในลักษณะการทำงานล้วนเป็นเหมือนคุณผ่านโปรแกรมของคุณที่สถานะของหน้าจอและรับกลับสถานะของหน้าจอด้วยการพิมพ์ "สวัสดีโลก" ดังนั้นในทางเทคนิคคุณกำลังโทรไปยังฟังก์ชั่นที่บริสุทธิ์และไม่มีผลข้างเคียง
จากนั้นฉันก็ผ่านแอปพลิเคชันของฉันและ: 1. ขั้นแรกให้สถานะแอปพลิเคชันทั้งหมดของฉันเป็นวัตถุระดับโลกเดียว (GameState) 2. ประการที่สองฉันทำให้ GameState ไม่เปลี่ยนรูป คุณไม่สามารถเปลี่ยนได้ หากคุณต้องการการเปลี่ยนแปลงคุณต้องสร้างสิ่งใหม่ ฉันทำสิ่งนี้โดยการเพิ่มตัวคัดลอกตัวเลือกที่จะเลือกหนึ่งหรือมากกว่าหนึ่งช่องที่มีการเปลี่ยนแปลง 3. สำหรับแต่ละแอปพลิเคชันฉันส่งผ่าน GameState เป็นพารามิเตอร์ ภายในฟังก์ชั่นหลังจากที่ทำสิ่งที่มันจะทำมันจะสร้าง GameState ใหม่และส่งคืน
ฉันมีคอร์ที่ใช้งานได้จริงได้อย่างไรและมีลูปด้านนอกที่ดึง GameState นั้นเข้าสู่เวิร์กโฟลว์หลักของแอปพลิเคชัน
คำถามของฉัน:
ตอนนี้ปัญหาของฉันคือ GameState มีวัตถุที่เปลี่ยนแปลงไม่ได้ประมาณ 15 รายการ ฟังก์ชั่นหลายอย่างในระดับต่ำสุดใช้งานได้กับวัตถุเหล่านั้นเพียงเล็กน้อยเท่านั้นเช่นการเก็บคะแนน สมมุติว่าฉันมีฟังก์ชันที่คำนวณคะแนน วันนี้ GameState ถูกส่งผ่านไปยังฟังก์ชั่นนี้ซึ่งปรับเปลี่ยนคะแนนโดยการสร้าง GameState ใหม่ด้วยคะแนนใหม่
มีบางอย่างเกี่ยวกับที่ดูเหมือนผิด ฟังก์ชั่นไม่ต้องการ GameState ทั้งหมด มันแค่ต้องการวัตถุคะแนน ดังนั้นฉันจึงอัปเดตเพื่อให้ผ่านคะแนนและคืนคะแนนเท่านั้น
ดูเหมือนจะสมเหตุสมผลแล้วฉันก็เลยไปต่อด้วยฟังก์ชั่นอื่น ๆ บางฟังก์ชั่นต้องการให้ฉันผ่านพารามิเตอร์ 2, 3 หรือ 4 จาก GameState แต่เมื่อฉันใช้รูปแบบไปจนถึงแกนด้านนอกของแอปพลิเคชันฉันจะผ่านสถานะแอปพลิเคชันมากขึ้นเรื่อย ๆ เช่นที่ด้านบนของลูปเวิร์กโฟลว์ฉันจะเรียกวิธีการที่จะเรียกวิธีการที่จะเรียกวิธีการอื่น ๆ ทุกวิธีลงไปในที่ที่มีการคำนวณคะแนน นั่นหมายความว่าคะแนนปัจจุบันจะถูกส่งผ่านไปยังเลเยอร์เหล่านั้นทั้งหมดเพียงเพราะฟังก์ชั่นที่ด้านล่างสุดจะทำการคำนวณคะแนน
ดังนั้นตอนนี้ฉันมีฟังก์ชั่นที่มีพารามิเตอร์หลายสิบครั้ง ฉันสามารถใส่พารามิเตอร์เหล่านี้ลงในวัตถุเพื่อลดจำนวนพารามิเตอร์ แต่จากนั้นฉันอยากให้คลาสนั้นเป็นตำแหน่งหลักของสถานะแอปพลิเคชันสถานะมากกว่าวัตถุที่สร้างขึ้นอย่างเรียบง่ายในช่วงเวลาของการโทรเพียงเพื่อหลีกเลี่ยงการผ่าน ในหลายพารามิเตอร์แล้วแกะออกมา
ดังนั้นตอนนี้ฉันสงสัยว่าปัญหาที่ฉันมีคือการทำงานของฉันซ้อนกันลึกเกินไป นี่คือผลลัพธ์ของการต้องการมีฟังก์ชั่นเล็ก ๆ ดังนั้นฉัน refactor เมื่อฟังก์ชั่นใหญ่และแยกมันเป็นฟังก์ชั่นเล็ก ๆ หลาย ๆ อัน แต่การทำเช่นนั้นจะทำให้เกิดลำดับชั้นที่ลึกกว่าและสิ่งใดก็ตามที่ส่งผ่านไปยังฟังก์ชั่นด้านในจะต้องส่งผ่านไปยังฟังก์ชั่นด้านนอกแม้ว่าฟังก์ชั่นด้านนอกจะไม่ทำงานบนวัตถุเหล่านั้นโดยตรง
ดูเหมือนว่าจะผ่าน GameState ไปตามทางเพื่อหลีกเลี่ยงปัญหานี้ แต่ฉันกลับไปที่ปัญหาดั้งเดิมของการส่งผ่านข้อมูลเพิ่มเติมไปยังฟังก์ชันมากกว่าความต้องการของฟังก์ชัน