2008-08-11 11 views
35

सबसे पहले, मुझे पता है कि जावा एप्लिकेशन कैसे बनाया जाए। लेकिन मैं हमेशा अपनी कक्षाओं को कहां रखना है, इस बारे में परेशान हूं। सख्ती से डोमेन उन्मुख फैशन में पैकेजों को व्यवस्थित करने के लिए समर्थक हैं, अन्य स्तरीय से अलग हैं।मुझे जावा एप्लिकेशन कैसे बनाना चाहिए, मैं अपनी कक्षा कहां रखूं?

मैं अपने आप को हमेशा पड़ा है साथ

  • नामकरण की समस्याओं,

तो,

  1. कहाँ आप अपने डोमेन विशिष्ट स्थिरांक रखूँ (और क्या है रखने इस तरह के एक वर्ग के लिए सबसे अच्छा नाम)?
  2. आप कहां सामान के लिए कक्षाएं डालते हैं जो बुनियादी ढांचागत और डोमेन विशिष्ट दोनों हैं (उदाहरण के लिए मेरे पास एक फ़ाइलस्टॉरेजस्ट्रेटी क्लास है, जो फ़ाइलों को डेटाबेस में या वैकल्पिक रूप से डेटाबेस में संग्रहीत करता है)?
  3. अपवाद कहां रखा जाए?
  4. क्या कोई मानक है जिसके लिए मैं संदर्भ कर सकता हूं?
+0

स्पष्ट रूप से कोई निश्चित उत्तर नहीं है, लेकिन थोड़ी देर के लिए maven2 का उपयोग करने के बाद मैं दी गई संरचना की सराहना करता हूं, और इसलिए मैं एक के रूप में मेवेन उत्तर घोषित करता हूं। (इसका मतलब यह नहीं है कि दूसरे गलत हैं, या कुछ भी) मुझे अभी एहसास हुआ है कि आपके निर्माण के शुरुआती चरणों के बारे में सोचना कितना आसान नहीं है, आप बस उन स्रोतों में अपने स्रोतों और स्रोतों को छोड़ दें और यह संकलित करें चींटी फाइलें और सामान बनाये बिना। – Mauli

उत्तर

21

मैं वास्तव में मेवेन के Standard Directory Layout की तरह आया हूं।

MyProject/src/main/java/com/acme/Widget.java 
MyProject/src/test/java/com/acme/WidgetTest.ava 

(यहाँ, दोनों src/मुख्य/जावा और src/परीक्षण: उत्पादन कोड के लिए एक और परीक्षण कोड की तरह तो के लिए एक -

मेरे लिए प्रमुख विचारों में से एक दो स्रोत जड़ें करने के लिए है/जावा स्रोत जड़ें हैं)।

लाभ:

  • आपका परीक्षण पैकेज है (या "डिफ़ॉल्ट") स्तर अपनी कक्षाओं के लिए परीक्षण के अंतर्गत पहुँच।
  • आप स्रोत स्रोत के रूप में src/test/java को छोड़कर केवल अपने उत्पादन स्रोतों को JAR में आसानी से पैकेज कर सकते हैं।वर्ग प्लेसमेंट और पैकेज के बारे में अंगूठे का

एक नियम:

सामान्य शब्दों में, अच्छी तरह से संरचित परियोजनाओं circular dependencies से मुक्त हो जाएगा। जानें कि वे कब खराब हैं (और जब वे not हैं), और JDepend या SonarJ जैसे टूल पर विचार करें जो उन्हें समाप्त करने में आपकी सहायता करेगा।

3

कक्षा नाम हमेशा वर्णनात्मक और आत्म व्याख्यात्मक होना चाहिए। यदि आपके वर्गों के लिए ज़िम्मेदारी के कई डोमेन हैं तो उन्हें शायद दोबारा प्रतिक्रिया दी जानी चाहिए।

इसी प्रकार आपके लिए पैकेज। उन्हें जिम्मेदारी के डोमेन द्वारा समूहीकृत किया जाना चाहिए। प्रत्येक डोमेन में इसका अपना अपवाद होता है।

आम तौर पर तब तक पसीना न पड़े जब तक कि आप उस बिंदु तक नहीं पहुंच जाते जहां यह जबरदस्त और फुलाया जा रहा है। फिर बैठ जाओ और कोड न करें, बस वर्गों को दोबारा दोहराएं, यह सुनिश्चित करने के लिए नियमित रूप से संकलन करें कि सबकुछ काम करता है। फिर जैसा आपने पहले किया था जारी रखें।

2

समूह से संबंधित कार्यक्षमता को एक साथ पैकेज का उपयोग करें।

आमतौर पर आपके पैकेज पेड़ का शीर्ष विशिष्टता की गारंटी के लिए आपके डोमेन नाम को उलट दिया जाता है (com.domain.subdomain), और फिर आमतौर पर आपके एप्लिकेशन के लिए एक पैकेज होगा। तो संबंधित क्षेत्र से है कि उप-विभाजन है, तो आपके FileStorageStrategy में जा सकते हैं, कहते हैं, com.domain.subdomain.myapp.storage, और फिर वहाँ विशिष्ट कार्यान्वयन/उपवर्गों हो सकता है/जो कुछ भी com.domain.subdomain.myapp.storage.file और com.domain.subdomain.myapp.storage.database में। ये नाम बहुत लंबा हो सकते हैं, लेकिन import उन्हें सभी फ़ाइलों के शीर्ष पर रखता है और आईडीई भी इसे प्रबंधित करने में सहायता कर सकते हैं।

अपवाद आमतौर पर उसी पैकेज में जाते हैं जो उन्हें फेंकने वाले वर्गों के रूप में जाते हैं, इसलिए यदि आपने कहा था, FileStorageException यह FileStorageStrategy के समान पैकेज में जाएगा। इसी प्रकार एक इंटरफ़ेस परिभाषित स्थिरांक एक ही पैकेज में होंगे।

वास्तव में ऐसा कोई मानक नहीं है, केवल सामान्य ज्ञान का उपयोग करें, और यदि यह सब बहुत गन्दा हो, रिफैक्टर!

0

एक चीज मैंने अतीत में की है - अगर मैं कक्षा का विस्तार कर रहा हूं तो मैं कोशिश करूँगा और उनके सम्मेलनों का पालन करूंगा। उदाहरण के लिए, स्प्रिंग फ्रेमवर्क के साथ काम करते समय, मेरे पास com.mydomain.myapp.web.servlet.mvc नामक पैकेज में मेरी एमवीसी कंट्रोलर कक्षाएं होंगी यदि मैं कुछ विस्तार नहीं कर रहा हूं तो मैं बस सबसे सरल चीज़ों के साथ जाता हूं। डोमेन ऑब्जेक्ट्स के लिए com.mydomain.domain (हालांकि यदि आपके पास डोमेन ऑब्जेक्ट्स का एक टन है तो यह पैकेज थोड़ा अनावश्यक हो सकता है)। डोमेन विशिष्ट स्थिरांक के लिए, मैं वास्तव में उन्हें सबसे संबंधित वर्ग में सार्वजनिक स्थिरांक के रूप में डालता हूं।उदाहरण के लिए, यदि मेरे पास "सदस्य" वर्ग है और अधिकतम सदस्य नाम लंबाई स्थिर है, तो मैंने इसे सदस्य वर्ग में रखा है। कुछ दुकानें अलग-अलग कॉन्स्टेंट कक्षा बनाती हैं लेकिन मुझे असंबद्ध संख्याओं और तारों को एक वर्ग में लंपने में मूल्य नहीं दिखता है। मैंने कुछ अन्य दुकानों को अलग-अलग कॉन्स्टेंट कक्षाओं को बनाकर इस समस्या को हल करने का प्रयास किया है, लेकिन यह समय की बर्बादी की तरह लगता है और नतीजा बहुत भ्रमित है। इस सेटअप का उपयोग करके, कई डेवलपर्स के साथ एक बड़ी परियोजना पूरी जगह पर स्थिरांक डुप्लिकेट कर रही है।

0

मुझे अपने वर्गों को एक दूसरे से संबंधित पैकेजों में तोड़ना पसंद है।

उदाहरण के लिए: मॉडल डेटाबेस से संबंधित कॉल

देखें क्लासेस कि तुम क्या देखते

नियंत्रण कोर कार्यक्षमता कक्षाएं

util किसी भी विविध से निपटने के लिए। कक्षाएं कि उपयोग किया जाता है (आम तौर पर स्थिर कार्यों)

आदि

1

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

10

मैं संगठित स्रोतों का एक बहुत बड़ा प्रशंसक हूँ, इसलिए मैं हमेशा निम्नलिखित निर्देशिका संरचना बनाने के लिए:

/src - for your packages & classes 
/test - for unit tests 
/docs - for documentation, generated and manually edited 
/lib - 3rd party libraries 
/etc - unrelated stuff 
/bin (or /classes) - compiled classes, output of your compile 
/dist - for distribution packages, hopefully auto generated by a build system 

/src में मैं डिफ़ॉल्ट जावा पैटर्न का उपयोग कर रहा: अपने डोमेन के साथ शुरू पैकेज का नाम (ऑर्ग .yourdomain.yourprojectname) और क्लास नाम ओओपी पहलू को दर्शाते हैं जो आप कक्षा के साथ बना रहे हैं (अन्य टिप्पणीकार देखें)। सामान्य पैकेज नाम जैसे उपयोग, मॉडल, देखें, ईवेंट उपयोगी भी हैं।

मैं SessionConstants या ServiceConstants डोमेन वर्गों का एक ही पैकेज में की तरह एक ही वर्ग में एक विशिष्ट विषय के लिए स्थिरांक डाल करने के लिए, करते हैं।

2

यूनिट परीक्षणों के लिए मुझे बहुत उपयोगी पाया गया एक चीज़ मेरे myApp/src/और myApp/test_src/निर्देशिका भी थी। इस तरह, मैं एक ही पैकेज में यूनिट परीक्षणों को कक्षाओं के परीक्षण के रूप में रख सकता हूं, और फिर भी जब मैं अपनी उत्पादन स्थापना तैयार करता हूं तो परीक्षण परीक्षणों को आसानी से बाहर कर सकता हूं।

2

संक्षिप्त उत्तर: मॉड्यूल के संदर्भ में अपने सिस्टम आर्किटेक्चर को खींचना, प्रत्येक तरफ परतों (जैसे देखें, मॉडल, दृढ़ता) में कटा हुआ प्रत्येक मॉड्यूल के साथ। फिर com.mycompany.myapp.somemodule.somelayer जैसी संरचना का उपयोग करें, उदा। com.mycompany.myapp.client.view या com.mycompany.myapp.server.model

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

मॉड्यूल के भीतर या छोटे एप्लिकेशन में, एप्लिकेशन परतों के लिए पैकेज का उपयोग करें।

  • com.mycompany.myapp.view
  • com.mycompany.myapp.model
  • com.mycompany.myapp: संभावना संकुल निम्नलिखित तरह बातें, वास्तुकला के आधार पर शामिल हैं। सेवाओं
  • com.mycompany.myapp.rules
  • com.mycompany.myapp.persi stence (या 'दाव' डेटा के लिए पहुँच परत)
  • com.mycompany.myapp.util (इस से सावधान इस्तेमाल किया जा रहा है जैसे यह 'विविध' थे)

इन परतों में से प्रत्येक के भीतर, यदि बहुत कुछ है तो कक्षाओं को समूहबद्ध करना स्वाभाविक है। यहां एक आम एंटी-पैटर्न अनावश्यक रूप से बहुत सारे पैकेज और उप-पैकेज के स्तर को पेश करना है ताकि प्रत्येक पैकेज में केवल कुछ कक्षाएं हों।

7

जहां मैं काम कर रहा हूं, हम मेवेन 2 का उपयोग कर रहे हैं और हमारे पास हमारी परियोजनाओं के लिए एक बहुत अच्छा आर्केटाइप है। लक्ष्य चिंताओं का एक अच्छा अलगाव प्राप्त करना था, इस प्रकार हमने कई मॉड्यूल (प्रत्येक एप्लिकेशन 'परत' के लिए एक) का उपयोग करके एक परियोजना संरचना को परिभाषित किया: - आम: अन्य परतों द्वारा उपयोग किया जाने वाला सामान्य कोड (उदाहरण के लिए, i18n) - संस्थाएं: डोमेन इकाइयां - भंडार: इस मॉड्यूल में दास इंटरफेस और कार्यान्वयन - सेवाएं-intf: सेवाओं के लिए इंटरफेस (उदाहरण के लिए, उपयोगकर्ता सेवा, ...) - सेवाओं-impl: सेवाओं के कार्यान्वयन (जैसे, UserServiceImpl) - वेब: वेब सामग्री के बारे में सब कुछ (जैसे, सीएसएस, JSPs, JSF पृष्ठों, ...) - ws: वेब सेवाओं

प्रत्येक मॉड्यूल की अपनी निर्भरताएं हैं (उदाहरण के लिए, भंडारों में जेपीए हो सकता है) और कुछ प्रोजेक्ट चौड़े हैं (इस प्रकार वे आम मॉड्यूल में हैं)। विभिन्न परियोजना मॉड्यूल के बीच निर्भरता स्पष्ट रूप से अलग चीजें (उदा।, वेब परत सेवा परत पर निर्भर करती है लेकिन रिपोजिटरी परत के बारे में नहीं जानता)।

प्रत्येक मॉड्यूल का अपना आधार पैकेज, उदाहरण के लिए यदि आवेदन पैकेज "com.foo.bar" है, तो हमारे पास है:

:

com.foo.bar.common 
com.foo.bar.entities 
com.foo.bar.repositories 
com.foo.bar.services 
com.foo.bar.services.impl 
... 

प्रत्येक मॉड्यूल मानक Maven परियोजना संरचना का सम्मान करता है

src\ 
    ..main\java 
    ...\resources 
    ..test\java 
    ...\resources 

किसी दिए गए परत के लिए यूनिट परीक्षण आसानी से \ src \ test के अंतर्गत अपना स्थान ढूंढते हैं ... डोमेन विशिष्टता वाली प्रत्येक चीज यह इकाई मॉड्यूल में है। अब FileStorageStrategy की तरह कुछ रिपोजिटरी मॉड्यूल में जाना चाहिए, क्योंकि हमें यह जानने की आवश्यकता नहीं है कि कार्यान्वयन क्या है। सेवा परत में, हम केवल भंडार इंटरफ़ेस को जानते हैं, हमें परवाह नहीं है कि विशिष्ट कार्यान्वयन क्या है (चिंताओं को अलग करना)।

  • चिंताओं में से स्पष्ट अलगाव
  • प्रत्येक मॉड्यूल एक जार (या वेब मॉड्यूल के मामले में एक युद्ध) के रूप में packageable है और इस तरह आसान कोड के लिए अनुमति देता है:

    इस दृष्टिकोण के लिए कई फायदे हैं पुन: उपयोग

  • अधिकतम स्वतंत्रता परियोजना के प्रत्येक भाग की (जैसे, हम मॉड्यूल Maven भंडार में स्थापित करने और एक अन्य परियोजना में यह पुन: उपयोग कर सकता है)

मैं यह करता है पता अपने सभी सवालों का जवाब न दें, लेकिन मुझे लगता है कि यह आपको सही रास्ते पर डाल सकता है और दूसरों के लिए उपयोगी साबित हो सकता है।

संबंधित मुद्दे