นี่เป็นรูปแบบอะไรและฉันควรทำอย่างไร


9

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

 var block:Block = new Block(gateway);

 //In the block class:
 this.gateway.player.setHealth(100);
 //Or:
 this.gateway.input.lock();

นี่เป็นรูปแบบซิงเกิลหรืออะไรซักอย่าง? ฉันควรทำสิ่งนี้หรือไม่

คำตอบ:


13

สิ่งนี้เรียกว่ารูปแบบการออกแบบวัตถุบริบทและดีกว่ารูปแบบซิงเกิล

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

ไม่เลยนี่ไม่ใช่ซิงเกิลมันดีกว่าซิงเกิล

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

พิจารณาบริบทที่แตกต่างกันตัวอย่างเช่น:

  • GameplayContext - เป็นเจ้าของผู้เล่นศัตรูรูปทรงเรขาคณิตระดับ ฯลฯ
  • InputContext - เป็นเจ้าของคีย์บอร์ดและเม้าส์, กิจกรรมอินพุต, ฯลฯ
  • GraphicsContext - เป็นเจ้าของพื้นผิวจัดการหน้าต่าง ฯลฯ
  • GlobalContext - เป็นเจ้าของ GameplayContext, GraphicsContext และ InputContext นี่คือที่ที่คุณต้องการใช้รูปแบบตัวระบุบริการเพื่อให้สามารถแลกเปลี่ยนบริบทบางอย่างสำหรับผู้อื่นได้ตามต้องการ และอาจจะสำหรับการทำซ้ำอย่างรวดเร็วและการทดสอบนี้ควรจะอยู่ในตัวแปรทั่วโลกจริง - เพียงแค่รู้ว่าเมื่อใดก็ตามที่คุณใช้มันคุณกำลังสร้างหนี้เทคโนโลยี

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


+1 คำตอบที่ดี ความกังวลเรื่องความเร็วหรือการทำเกลียวบางอย่างไม่ได้นำมาใช้จริงในบริบทนี้ (ActionScript3 ไม่รองรับการทำเกลียวและกลไกการปรับปรุงความเร็วจำนวนมากที่ทำงานใน C ++ ไม่ได้ใช้เมื่อใช้ AS3)
bummzack

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

0

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

หากนี่เป็นรูปแบบซิงเกิลคุณจะต้อง:

AudioManager.getInstance().playSound(XY);

ในกรณีที่คุณอาจมี:

this.gateway.getAudioManager().playSound(XY);

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

ข้อเสียเปรียบของวิธีการของคุณคือคุณจะต้องผ่านรอบgatewayทุกที่ รูปแบบบริการระบุตำแหน่ง (เสนอโดยโจ Wreschnig ในนี้ด้าย) ดูเหมือนเปลี่ยนที่ดีสำหรับ "รูปแบบประตูของคุณ"

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


-2

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


คำถามมีการเปลี่ยนแปลงอย่างมีนัยสำคัญตั้งแต่ฉันทำคำตอบนี้พอที่จะไม่คุ้มค่าที่จะแก้ไข
Gregory Avery-Weir

2
นอกเหนือจากชื่อไม่มีอะไรเปลี่ยนแปลงในคำถาม
bummzack

1
อะไร? ไม่มีการเปลี่ยนแปลงอะไรนอกจากชื่อ -1
AttackHobo

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