में युग्मन और वैश्विक स्थिति को खत्म करना मैं एक गेम (अपने स्वयं के भौतिकी इंजन लिखना) पर काम कर रहा हूं, और इसे लिखने में अच्छी डिजाइन का पालन करने की कोशिश कर रहा हूं। हाल ही में, मैं कई हार्ड-टू-बग बग्स में चल रहा हूं, और इन बगों को आसान बनाने के लिए, मैं यूनिट-टेस्ट लिखने की कोशिश कर रहा हूं। ऐसा करना मुश्किल रहा है, इस तथ्य के कारण कि मेरे कई घटक कसकर युग्मित हैं, खासकर game
मॉड्यूल के लिए।"गेम" सिंगलटन
मेरी game
मॉड्यूल में मैं एक सिंगलटन वर्ग उदाहरण है, जो, हालांकि वर्तमान खेल राज्य, समय, खेल की घटनाओं, आदि धारण निर्यात this पढ़ने के बाद और शोध कैसे इस युग्मन को कम करने के माध्यम से, मैं कोशिश करने के लिए तय कर लिया है और कक्षा को फिर से लिखना जैसे कि यह अब सिंगलटन नहीं है।
विचार GameState
कक्षा का उपयोग करना है, और इन वस्तुओं को हर जगह पास करना है, ताकि यूनिट-टेस्ट परीक्षणों के लिए न्यूनतम राज्य बना सकें। अधिकांश फ़ंक्शंस तब गेम स्टेटस का फ़ंक्शन बन जाते हैं, और एक नया गेम स्टेटस लौटाते हैं। हालांकि, मैंने कुछ डिज़ाइन समस्याओं में भाग लिया है:
मेरी इकाई ऑब्जेक्ट्स की स्थिति और वेग पाइथन गुण हैं जो वर्तमान समय के अनुसार गणना की जाती हैं। इसका मतलब यह है कि मैं इसे GameState
ऑब्जेक्ट में फ़ंक्शन के रूप में पुनः लिखने के बिना बस पास नहीं कर सकता (जिसके परिणामस्वरूप icky वाक्यविन्यास)। कोड उदाहरण:
class Entity:
@property
def position(self):
"""Interpolate the position from the last known position from that time."""
# Here, the game class instance is referenced directly, creating coupling.
dt = game.game_time - self._last_valid_time
# x_f = x_i + v_i*t + 1/2 at^2
return self._position + self._velocity * dt + .5 * self._acceleration * dt**2
मैं यह कैसे हल करने पर कुछ शोध किया है, और Dependency Injection भर में भाग गया। अनिवार्य रूप से, मैं प्रत्येक इकाई के प्रारंभकर्ता में गेमस्टेट 'गेटर' ऑब्जेक्ट पास कर सकता हूं। सभी गेमस्टेट 'गेटर' ऑब्जेक्ट्स बस वर्तमान स्थिति को वापस कर देंगे। उदाहरण GameStateGetter
वर्ग:
class GameStateGetter:
_CurrentState = None
def update(self, new_state):
GameStateGetter._CurrentState = new_state
def __getattr__(self, name):
# GameState object properties are immutable, so this can't cause issues
return getattr(GameStateGetter._CurrentState, name)
अब मेरे सवालों के लिए
।
- गेमस्टेट 'गेटर' ऑब्जेक्ट्स का उपयोग करना भी एक अच्छा विचार होगा?
एक समस्या यह है वर्तमान खेल राज्य अद्यतन करने के लिए इंटरफेस होगा (मैं एक update
विधि को परिभाषित किया है, लेकिन यह एक अजीब इंटरफ़ेस की तरह लगता है)। साथ ही, यह देखते हुए कि वैश्विक चर के साथ समस्या अप्रत्याशित प्रोग्राम स्थिति है, यह वास्तव में इसे रोक नहीं पाएगी।
- वहाँ एक और तरीका है करने के लिए "इंजेक्षन"
Entity
वर्ग केposition
संपत्ति कोgame
निर्भरता है?
आदर्श रूप में, मैं चीजों को सरल रखना चाहता हूं। एक GameStateGetter
वर्ग बहुत सार लगता है (भले ही कार्यान्वयन सरल है)। यह अच्छा होगा अगर मेरी संपत्तियां वर्तमान स्थिति को पूरी तरह से पास कर सकें।
किसी भी मदद के लिए अग्रिम धन्यवाद!
अधिक आम शब्द है "प्रदाता।" (जो आपको गेटर विधियों के साथ भ्रमित प्रदाता वस्तुओं से भ्रमित करता है।) और हाँ, उनका उपयोग करना एक अच्छा विचार है। निर्भरता इंजेक्शन हिंसा की तरह है: यदि यह काम नहीं करता है, तो आप शायद इसके पर्याप्त उपयोग नहीं कर रहे हैं। –
@RobertRossney धन्यवाद! निर्भरता इंजेक्शन की मेरी नई समझ अब ' प्रदाता' नामक कक्षाओं के साथ पहले देखे गए कुछ कोड से जुड़ती है। शायद कुछ अतिरिक्त जानकारी के साथ, इसे एक उत्तर के रूप में स्वीकार किया जा सकता है! –
Darthfett