2010-03-24 7 views
14

ठीक है मेरे पास 2 वास्तव में बड़ी कक्षाएं> 1k लाइनें हैं जिन्हें मैंने वर्तमान में कई में विभाजित किया है। फिर वे एकाधिक विरासत का उपयोग कर पुनः संयोजित हो जाते हैं। अब मैं सोच रहा हूं, अगर ऐसा करने के लिए कोई क्लीनर/बेहतर और पाइथोनिक तरीका है। उन्हें पूरी तरह फैक्टरिंग के परिणामस्वरूप self.otherself.do_something कॉल की अंतहीन मात्रा होगी, जो मुझे नहीं लगता कि यह तरीका किया जाना चाहिए।पायथन क्लास डिज़ाइन - समूह की कार्यक्षमता के लिए कई वर्गों में बड़ी कक्षाओं को विभाजित करना

from gui_events import GUIEvents # event handlers 
from gui_helpers import GUIHelpers # helper methods that don't directly modify the GUI 

# GUI.py 
class GUI(gtk.Window, GUIEvents, GUIHelpers): 
    # general stuff here stuff here 

एक समस्या यह है इस Pylint मुझे अरबों देने शिकायत कर रहा है का परिणाम "नहीं कहा init" है कि/"अपरिभाषित विशेषता"/"विशेषता पहुँचा:

चीज़ें यहाँ स्पष्ट करने के लिए क्या यह वर्तमान की तरह लग रहा है परिभाषा से पहले "चेतावनियां।

संपादित करें:
आप कोड पर एक नज़र लेने के लिए, अपने आप को क्या पूरी बात वास्तव में है के बारे में एक तस्वीर बनाने के लिए कर सकते हैं।
http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/

कृपया ध्यान दें, मैं वास्तव में इस बात संभव के रूप में सूखा रखने के लिए कुछ भी कोशिश कर रहा हूँ, मैं कोड दोहराव, केवल एक चीज यह शिकायत के बारे में आयात कर रहे हैं पता लगाने के लिए pylint उपयोग कर रहा हूँ।

+0

कुछ जोड़ नहीं है। सवाल कहता है "> 1k लाइन प्रत्येक"। भंडार में वास्तविक कोड 356 लाइनें है। कृपया प्रश्न या लिंक को ठीक करें। –

+0

आपको समेकित करने की आवश्यकता है: http://github.com/BonsaiDen/Atarashii/blob/next/atarashii/usr/share/pyshared/atarashii/gui.py http://github.com/BonsaiDen/Atarashii/blob/ अगली/atarashii/usr/share/pyshared/atarashii/gui_events.py और http://github.com/BonsaiDen/Atarashii/blob/next/atarashii/usr/share/pyshared/atarashii/gui_helpers.py क्योंकि मैंने पहले से ही विभाजित किया है सामान (वर्तमान में केवल 968 लाइन है, क्योंकि मैंने हाल ही में कुछ फाइलों को अन्य फाइलों पर ले जाया है)। दृश्य * फ़ाइलों को भी देखें, जो एक साथ 1,1k लाइनें हैं। –

उत्तर

6

यदि आप सब कुछ एक बड़ी कक्षा में जोड़ना चाहते हैं तो इसे एकाधिक विरासत का उपयोग करना चाहते हैं (यह करने के लिए यह समझ में आ सकता है), तो आप प्रत्येक मूल वर्ग को दोबारा कर सकते हैं ताकि प्रत्येक विधि और संपत्ति निजी हो (' __ ') या उस वर्ग के लिए अद्वितीय 2-3 वर्ण उपसर्ग है। उदाहरण के लिए, आपके GUIEvents वर्ग में सभी विधियां और गुण ge_ से शुरू हो सकते हैं, GUIHelpers में सब कुछ gh_ से शुरू हो सकता है। ऐसा करके, आप अलग-अलग उप-वर्ग उदाहरणों (self.ge.doSomething() बनाम self.ge_doSomething()) का उपयोग करने की कुछ स्पष्टता प्राप्त करेंगे, और आप विवादित सदस्य नामों से बचेंगे, जो कि इस तरह के बड़े वर्गों को एक में जोड़ते समय मुख्य जोखिम है।

फ़ाइल a_part_1.py में:

def add(self, n): 
    self.n += n 
def __init__(self, n): 
    self.n = n 

और मुख्य वर्ग फ़ाइल में:

import a_part_1 

class A: 
    __init__ = a_part_1.__init__ 
    add = a_part_1.add 

या यदि आप नहीं चाहते

+0

मुझे लगता है कि जिस तरह से मैं यहां जाऊंगा, क्योंकि 1. खोज/प्रतिस्थापन के साथ करना आसान है, 2. यह विवादों का मौका कम कर देगा, मैं इसके बजाय um_get_items जैसे अधिक सामान्य नामों का उपयोग करने में सक्षम हूं, इसके बजाय (update_messages) .get_messages और 3. जैसा कि आपने पहले ही कहा है कि यह कोड में स्पष्टता लाएगा और दिखाएगा कि विधियों की उत्पत्ति कहां है। सब कुछ यह बहुत आसान है, शायद मैं इस बात को प्रोग्राम करने में 5 सप्ताह खर्च करने के बाद जटिलता के बारे में सोच रहा हूं: डी –

1

मुझे लगता है कि यह पाइथन समस्या की तुलना में एक सामान्य ओओ-डिजाइन समस्या से अधिक है। पाइथन बहुत अधिक आपको क्लासिक ओओपी उपकरण देता है, जो आसानी से पैक किया जाता है। (? क्या जैसे GUIEvents और GUIHelpers वर्गों को शामिल करते हैं): अजगर कई प्रोग्रामिंग मानदंड का समर्थन करता है, और अक्सर सबसे अच्छा समाधान है आप और अधिक विस्तार से समस्या का वर्णन होगा विचार करने के लिए

एक अजगर-विशिष्ट पहलू पीछा कर रहा है ओओपी नहीं यह यहां मामला हो सकता है। लेकिन फिर, आपको एक सार्थक उत्तर प्राप्त करने के लिए अधिक जानकारी में फेंकना होगा।

+0

आप यहां कक्षाओं पर एक नज़र डाल सकते हैं: http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/ GUIEvents अधिकतर सामान को संभालने के बारे में है जब उपयोगकर्ता ने क्लिक किया बटन। GUIHelpers लेबल और अन्य जैसे कुछ छोटी चीजें सेट करता है, और कुछ उपयोगिता कार्यों जैसे is_ready प्रदान करता है। मैं अभी भी यह तय करने के साथ पूरी तरह से नहीं कर रहा हूं कि कौन से तरीके "सबक्लास" में से प्रत्येक के हैं। –

0

मॉडल-व्यू-कंट्रोलर डिज़ाइन को लागू करके आपका कोड काफी सुधार किया जा सकता है। आपके जीयूआई और टूल कैसे सेट किए जाते हैं, इस पर निर्भर करते हुए, आप अपने जीयूआई के "विजेटिंग" भागों से भी लाभ उठा सकते हैं, ताकि एक विशाल मॉडल-व्यू-कंट्रोलर होने के बजाय, आपके पास एक मुख्य मॉडल-व्यू-कंट्रोलर है जो एक गुच्छा का प्रबंधन करता है छोटे मॉडल-व्यू-कंट्रोलर, प्रत्येक आपके जीयूआई के अलग-अलग हिस्सों के लिए। यह आपको कई कक्षाओं में अपना टूल और जीयूआई तोड़ने की अनुमति देगा, और आप इसे बनाए रखने के लिए आवश्यक कोड की कुल मात्रा को कम करने, इसके भाग का पुन: उपयोग करने में सक्षम हो सकते हैं।

जबकि पायथन कई प्रोग्रामिंग प्रतिमानों का समर्थन करता है, जीयूआई उपकरण के लिए, सबसे अच्छा समाधान लगभग ऑब्जेक्ट ओरिएंटेड डिज़ाइन होगा।

+0

समस्या यह है कि मैं वर्तमान में पूरी चीज को और भी कम करने का कोई तरीका नहीं देख रहा हूं, संवाद/ट्रे आइकन और एचटीएमएल व्यू पहले से ही अपने वर्गों में हैं, इसलिए यह बड़ी जीयूआई चीज वर्तमान में केवल उन लोगों के बीच बाध्यों का प्रबंधन कर रही है जैसे सामान स्टेटसबार। इसके अलावा मैंने पहले से ही मौत के लिए कोड डाला है ... केवल एक चीज जिसे मैं इमेजिंग कर सकता हूं, जीयूआई को एक घटक में विभाजित कर रहा है जो वास्तव में दृश्यमान सामग्री को संशोधित करता है और दूसरा सिर्फ घटनाओं को संभालने में सक्षम बनाता है, लेकिन इसका परिणाम स्वयं ही होगा। foo कॉल:/ –

5

मॉडल की वास्तविक कक्षा अवधारणाओं को ढूंढकर शुरू करें कि आपके एप्लिकेशन को काम करने की आवश्यकता है। वे कक्षाओं के लिए प्राकृतिक उम्मीदवार हैं।

जितना संभव हो सके एकाधिक विरासत से बचें; यह शायद ही कभी उपयोगी और हमेशा कुछ उलझन में है। इसके बजाय, कार्यात्मक संरचना ("एचएएस-ए" संबंधों) का उपयोग अन्य वस्तुओं से बने अपने ऑब्जेक्ट्स के समृद्ध गुण देने के लिए करें।

प्रत्येक विधि को बनाने के लिए याद रखें एक छोटी, विशिष्ट चीज़ करें; यह जरूरी तरीकों को तोड़ने में शामिल है जो बहुत सी चीजें छोटे टुकड़ों में करते हैं।

रिएक्टर मामले जहां आपको कई अन्य विधियां मिलती हैं, वे एक-दूसरे की कार्यक्षमता को डुप्लिकेट कर रहे हैं; यह एक अलग वर्ग में होने के लायक कार्यक्षमता के प्राकृतिक संग्रह को खोजने का एक और तरीका है।

+1

+1: "2 वास्तव में बड़ी कक्षाएं> 1k लाइनें" ओच। यह स्पष्ट रूप से ओओ डिजाइन के बिंदु को याद करता है। एक वर्ग में सभी इवेंट हैंडलर स्पष्ट रूप से गलत हैं। इवेंट हेल्पर्स क्लास डिज़ाइन नहीं है। –

0

एक संभावना यह वर्ग विशेषताओं के लिए आयात कार्यों आवंटित करने के लिए है नई विधियों को जोड़ने पर मुख्य फ़ाइल को अपडेट करने के लिए:

class A: pass 

import a_part_1 
for k, v in a_part_1.__dict__.items(): 
    if callable(v): 
     setattr(A,k,v) 
संबंधित मुद्दे