जावा में हेक्सागोनल आर्किटेक्चर: बिना दर्द के साफ लॉजिक

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: आपका एप्लिकेशन उसका डेटाबेस क्यों नहीं है

\n\n

कल्पना करें कि आप एक घर बना रहे हैं। नींव, दीवारें, छत — सब कुछ सोच-समझकर बनाया गया है। लेकिन एक साल बाद आप वायरिंग बदलने का फैसला करते हैं। और तब पता चलता है कि तार कंक्रीट में दबे हुए हैं, और सॉकेट सरिया से वेल्डेड हैं। एक स्विच बदलने के लिए आधा घर गिराना पड़ता है।

\n\n

लगभग ऐसा ही एक क्लासिक जावा एप्लिकेशन दिखता है, जहाँ बिजनेस लॉजिक फ्रेमवर्क, डेटाबेस या REST-कंट्रोलर के साथ कसकर जुड़ा होता है। आप PostgreSQL से MongoDB पर स्विच करना चाहते हैं? Spring MVC से JAX-RS पर कंट्रोलर फिर से लिखना चाहते हैं? रिफैक्टरिंग के नरक में आपका स्वागत है।

\n\n

समाधान है — हेक्सागोनल आर्किटेक्चर (जिसे "पोर्ट और एडेप्टर" भी कहा जाता है, या एलिस्टेयर कोबर्न की व्याख्या में "क्लीन आर्किटेक्चर")। यह कोई चांदी की गोली नहीं है, लेकिन यह आपके एप्लिकेशन को लचीला, परीक्षण योग्य और बाहरी दुनिया से स्वतंत्र बनाने का एक तरीका है।

\n\n

आज हम जावा में हेक्सागोनल आर्किटेक्चर को कोड के वास्तविक उदाहरणों के साथ समझेंगे, बिना फालतू बातों और अमूर्त चर्चाओं के। चलिए शुरू करते हैं।

\n\n

हेक्सागोनल आर्किटेक्चर (पोर्ट और एडेप्टर) क्या है?

\n\n

सार सरल है: आपका एप्लिकेशन एक कोर (core) है जिसमें बिजनेस लॉजिक होता है। कोर के चारों ओर एक "षट्भुज" (वास्तव में मनमानी संख्या में भुजाएँ) होता है, जिसके माध्यम से बाहरी दुनिया कोर के साथ संवाद करती है।

\n\n

प्रत्येक भुजा का अपना पोर्ट (इंटरफ़ेस) होता है। और एडेप्टर किसी विशिष्ट तकनीक के लिए पोर्ट का कार्यान्वयन है। उदाहरण के लिए:

\n
    \n
  • पोर्ट "UserRepository" — एडेप्टर "JpaUserRepository" या "MongoUserRepository"
  • \n
  • पोर्ट "SendNotification" — एडेप्टर "EmailSender" या "SmsSender"
  • \n
\n\n

मुख्य नियम: कोर बाहरी लाइब्रेरी, डेटाबेस, वेब फ्रेमवर्क के बारे में कुछ नहीं जानता। वह केवल अपने पोर्ट (इंटरफ़ेस) के बारे में जानता है। यह कई लाभ प्रदान करता है:

\n
    \n
  • इन्फ्रास्ट्रक्चर से स्वतंत्रता — लॉजिक को छुए बिना DB या फ्रेमवर्क बदलें।
  • \n
  • परीक्षण योग्यता — बिजनेस लॉजिक को Spring कॉन्टेक्स्ट या डेटाबेस शुरू किए बिना परीक्षण किया जा सकता है।
  • \n
  • पठनीयता — कोर कोड डोमेन की कहानी बताता है, तकनीकी विवरण नहीं।
  • \n
\n\n

प्रोजेक्ट संरचना: कोड को कैसे व्यवस्थित करें

\n\n

पैकेज संरचना का कोई एक सही तरीका नहीं है, लेकिन मैं DDD (Domain-Driven Design) और हेक्सागोनल सिद्धांतों पर आधारित एक सिद्ध विकल्प प्रस्तुत करता हूँ:

\n\n
com.example.app\n├── domain\n│   ├── model          // एंटिटी, Value Objects\n│   ├── port           // पोर्ट इंटरफ़ेस (inbound/outbound)\n│   └── service        // बिजनेस सर्विस (use cases)\n├── adapter\n│   ├── inbound\n│   │   ├── rest       // REST-कंट्रोलर (इनकमिंग एडेप्टर)\n│   │   └── messaging  // Kafka/RabbitMQ सुनने वाले\n│   └── outbound\n│       ├── persistence // JPA, JDBC, MongoDB रिपॉजिटरी\n│       └── client      // HTTP-क्लाइंट, बाहरी API\n└── config             // Spring कॉन्फ़िगरेशन (यदि उपयोग कर रहे हैं)\n
\n\n

ध्यान दें: domain adapter से कुछ भी इम्पोर्ट नहीं करता है। यह महत्वपूर्ण है। यदि आप domain में @Entity या @RestController देखते हैं — तो आर्किटेक्चर टूट गया है।

\n\n

उदाहरण: ऑर्डर प्रबंधन प्रणाली

\n\n

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

\n\n

चरण 1. डोमेन मॉडल (domain/model)

\n\n
// Order.java\npublic class Order {\n    private final OrderId id;\n    private final List<OrderItem> items;\n    private OrderStatus status;\n\n    public Order(List<OrderItem> items) {\n        this.id = new OrderId(UUID.randomUUID().toString());\n        this.items = Collections.unmodifiableList(items);\n        this.status = OrderStatus.PENDING;\n    }\n\n    public void confirm() {\n        if (status != OrderStatus.PENDING) {\n            throw new IllegalStateException("Only PENDING orders can be confirmed");\n        }\n        this.status = Ord                

ब्लॉग

पुस्तक अनुशंसाएँ