ฟังก์ชั่นโปรแกรมมิงจัดการสถานการณ์ที่วัตถุเดียวกันถูกอ้างอิงจากหลาย ๆ ที่ได้อย่างไร?


10

ฉันกำลังอ่านและได้ยินว่าผู้คน (บนเว็บไซต์นี้) ชื่นชมกระบวนทัศน์การเขียนโปรแกรมการทำงานเป็นประจำโดยเน้นว่าการมีทุกสิ่งที่ไม่เปลี่ยนรูปนั้นดีเพียงใด ผู้คนเสนอวิธีการนี้แม้ในภาษา OO ที่จำเป็นแบบดั้งเดิมเช่น C #, Java หรือ C ++ ไม่เพียง แต่ในภาษาที่ใช้งานได้จริงเท่านั้นเช่น Haskell ที่บังคับใช้โปรแกรมนี้

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

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

ตัวอย่างแรกจะเป็นของฉัน# เกม C ฉันพยายามที่จะทำในเวลาว่างของฉัน มันเป็นเกมบนเว็บแบบเปิดที่ผู้เล่นทั้งสองมีทีมจาก 4 มอนสเตอร์และสามารถส่งมอนสเตอร์จากทีมของพวกเขาไปยังสนามรบซึ่งมันจะเผชิญหน้ากับสัตว์ประหลาดที่ถูกส่งโดยผู้เล่นฝ่ายตรงข้าม ผู้เล่นสามารถจำสัตว์ประหลาดจากสนามรบและแทนที่พวกมันด้วยสัตว์ประหลาดอีกตัวจากทีมของพวกเขา (คล้ายกับโปเกมอน)

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

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

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

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

สิ่งนี้มาพร้อมกับปัญหาอย่างน้อย 2 ประการ:

  1. ลำดับชั้นสามารถจะลึกกว่าตัวอย่างนี้ง่ายเพียง->Battlefield Monsterฉันต้องทำการคัดลอกฟิลด์ทั้งหมดยกเว้นหนึ่งและส่งคืนวัตถุใหม่จนลำดับชั้นนี้ นี่จะเป็นรหัสสำเร็จรูปซึ่งฉันพบว่าน่ารำคาญโดยเฉพาะอย่างยิ่งเนื่องจากการเขียนโปรแกรมการทำงานควรจะลดสำเร็จรูป
  2. อย่างไรก็ตามปัญหาที่รุนแรงยิ่งกว่านั้นคือสิ่งนี้จะนำไปสู่ข้อมูลที่ไม่ซิงค์กัน สัตว์ประหลาดที่อยู่ในสนามจะเห็นสุขภาพลดลง แม้กระนั้นสัตว์ประหลาดตัวนี้ซึ่งอ้างอิงจากผู้เล่นที่ควบคุมมันTeamจะไม่ ถ้าฉันใช้รูปแบบที่จำเป็นแทนการเปลี่ยนแปลงข้อมูลทุกอย่างจะสามารถมองเห็นได้ทันทีจากที่อื่น ๆ ของรหัสและในกรณีเช่นนี้ฉันคิดว่ามันสะดวกจริง ๆ - แต่วิธีที่ฉันได้สิ่งนี้เป็นสิ่งที่ผู้คนพูดอย่างแม่นยำผิดกับสไตล์ที่จำเป็น!
    • ตอนนี้มันเป็นไปได้ที่จะจัดการกับปัญหานี้โดยการเดินทางไปTeamหลังจากการโจมตีแต่ละครั้ง นี่คืองานพิเศษ อย่างไรก็ตามถ้าหากสัตว์ประหลาดสามารถอ้างอิงได้ในภายหลังจากที่อื่น ๆ ? จะเป็นอย่างไรถ้าฉันมาพร้อมความสามารถที่ทำให้สัตว์ประหลาดมุ่งเน้นไปที่สัตว์ประหลาดตัวอื่นที่ไม่จำเป็นต้องอยู่บนสนาม (ฉันกำลังพิจารณาความสามารถดังกล่าว) ฉันจะจำได้หรือไม่ว่าจะต้องเดินทางไปยังสัตว์ประหลาดที่มุ่งเน้นทันทีหลังจากการโจมตีแต่ละครั้ง? ดูเหมือนว่าจะเป็นระเบิดเวลาที่จะระเบิดเมื่อรหัสซับซ้อนขึ้นดังนั้นฉันคิดว่ามันไม่มีทางออก

แนวคิดสำหรับการแก้ปัญหาที่ดีกว่ามาจากตัวอย่างที่สองของฉันเมื่อฉันประสบปัญหาเดียวกัน ในสถาบันการศึกษาเราได้รับคำสั่งให้เขียนล่ามภาษาที่เราออกแบบเองที่ Haskell (นี่คือวิธีที่ฉันถูกบังคับให้เริ่มเข้าใจว่า FP คืออะไร) ปัญหาปรากฏขึ้นเมื่อฉันใช้งานการปิด ขอบเขตเดียวกันนี้สามารถอ้างอิงได้จากหลาย ๆ ที่อีกครั้ง: ผ่านตัวแปรที่เก็บขอบเขตนี้และเป็นขอบเขตหลักของขอบเขตที่ซ้อนกัน! เห็นได้ชัดว่าหากมีการเปลี่ยนแปลงในขอบเขตนี้ผ่านการอ้างอิงใด ๆ ที่ชี้ไปที่การเปลี่ยนแปลงนี้จะต้องสามารถมองเห็นได้ผ่านการอ้างอิงอื่นทั้งหมด

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

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

อย่างไรก็ตามฉันสามารถเห็นปัญหาอีกครั้งด้วยวิธีการนี้ที่ป้องกันไม่ให้ฉันยอมรับมันโดยไม่ลังเลว่าจะเป็นวิธีแก้ปัญหา:

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

ผมก็ยังจะเขียนเกี่ยวกับปัญหา asecond ที่ดูเหมือนว่าจะรุนแรงมากขึ้น: วิธีการนี้จะเปิดตัวหน่วยความจำรั่ว โดยปกติแล้ววัตถุที่ไม่สามารถเข้าถึงได้จะถูกเก็บรวบรวมขยะ อย่างไรก็ตามวัตถุที่อยู่ในพจนานุกรมกลางไม่สามารถรวบรวมขยะได้แม้ว่าจะไม่มีวัตถุที่สามารถเข้าถึงได้ที่อ้างถึง ID เฉพาะนี้ และในขณะที่การตั้งโปรแกรมอย่างระมัดระวังในทางทฤษฎีสามารถหลีกเลี่ยงการรั่วไหลของหน่วยความจำ (เราสามารถดูแลการลบแต่ละวัตถุออกจากพจนานุกรมกลางด้วยตนเองเมื่อมันไม่ต้องการอีกต่อไป) นี่เป็นข้อผิดพลาดและ FP โฆษณาเพื่อเพิ่มความถูกต้องของโปรแกรม ไม่ใช่วิธีที่ถูกต้อง

อย่างไรก็ตามฉันพบในเวลาที่ดูเหมือนว่าจะเป็นปัญหาที่แก้ไขแล้ว Java นำเสนอWeakHashMapที่สามารถใช้เพื่อแก้ไขปัญหานี้ C # จัดให้มีสิ่งอำนวยความสะดวกที่คล้ายกัน - ConditionalWeakTable- แม้ว่าจะเป็นไปตามเอกสาร แต่ก็มีความหมายที่จะใช้โดยคอมไพเลอร์ และใน Haskell เรามีSystem.Mem.Weak

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

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


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

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

2
อย่านำความไม่แน่นอนและความไม่เปลี่ยนรูปมาเป็นความเชื่อทางศาสนา มีสถานการณ์ที่แต่ละคนดีกว่าคนอื่นความไม่เปลี่ยนแปลงไม่ได้ดีกว่าเสมอเช่นการเขียนชุดเครื่องมือ GUI ที่มีชนิดข้อมูลที่ไม่เปลี่ยนรูปจะเป็นฝันร้ายที่แน่นอน
whatsisname

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

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

คำตอบ:


19

Function Programming จัดการกับวัตถุที่อ้างอิงจากหลาย ๆ ที่ได้อย่างไร มันขอเชิญคุณมาเยี่ยมชมโมเดลของคุณอีกครั้ง!

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

คุณสามารถอ่านเกี่ยวกับความสนุกที่ทีม Factorio มีต่อการทำให้สิ่งนี้ทำงานได้ดีในบางสถานการณ์ นี่เป็นภาพรวมโดยย่อของโมเดลของพวกเขา:

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

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

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

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

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

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

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

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

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

  1. ประมวลผลอินพุตและสร้างเหตุการณ์ที่สอดคล้องกัน
  2. สร้างกิจกรรมภายใน (เช่นเนื่องจากการชนกันของวัตถุ ฯลฯ )
  3. ใช้กิจกรรมกับสัตว์ประหลาดที่ไม่เปลี่ยนรูปแบบในปัจจุบันเพื่อสร้างสัตว์ประหลาดใหม่สำหรับขีดถัดไป - การคัดลอกสถานะเก่าที่ไม่เปลี่ยนแปลงเท่าที่จะทำได้ แต่การสร้างวัตถุสถานะใหม่ที่จำเป็น
  4. เรนเดอร์และทำซ้ำสำหรับเห็บถัดไป

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

ขอขอบคุณที่บันทึกจาก @ AaronM.Eshbach เน้นว่านี่เป็นโดเมนปัญหาที่คล้ายกันกับEvent SourcingและรูปแบบCQRSซึ่งคุณกำลังจำลองการเปลี่ยนแปลงสถานะในระบบกระจายเป็นชุดของเหตุการณ์ที่ไม่เปลี่ยนรูปในช่วงเวลาหนึ่ง ในกรณีนี้เราน่าจะพยายามล้างข้อมูลแอพฐานข้อมูลที่ซับซ้อนโดยแยก (ตามชื่อแนะนำ!) คำสั่ง mutator ที่จัดการจากระบบสืบค้น / ดู ซับซ้อนมากขึ้น แต่มีความยืดหยุ่นมากขึ้น


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

@ AaronM.Eshbach นั่นแหละ! คุณรังเกียจไหมถ้าฉันใส่ความคิดเห็น / การอ้างอิงของคุณไว้ในคำตอบ? มันทำให้ฟังดูมีสิทธิ์มากกว่า ขอบคุณ!
SusanW

ไม่แน่นอนโปรดทำ
Aaron M. Eshbach

3

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

p1 - send m1 to battlefield
p2 - send m2 to battlefield
m1 - attacks m2 (2 dam)
m2 - attacks m1 (10 dam)
p1 - retreats m1

ฯลฯ

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

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