PHP Academy · पाठ

एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी

एग्रीगेट से इनवेरिएंट सुरक्षित करें और उन्हें सुव्यवस्थित ढंग से स्थायी करें।

पाठ 2, कुल 4 में से13 चरण

एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी, CoddyKit पर PHP Academy का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह PHP Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

अपरिवर्तनीय शर्तों की रक्षा

इकाइयाँ और मान-वस्तुएँ तैयार हो जाने के बाद, आपको ऐसे प्रतिरूप चाहिए जो उनके समूहों को सुसंगत रखें और उन्हें साफ़-सुथरे ढंग से स्थायी रूप से सहेजें। DDD इसका उत्तर तीन सामरिक प्रतिरूपों से देता है: समुच्चय (एक सुसंगति सीमा), भंडार (संग्रह-जैसा स्थायी भंडारण अमूर्तीकरण) और निर्माणक (जटिल निर्माण)। यह पाठ दिखाता है कि PHP में ये एक साथ कैसे काम करते हैं।

समुच्चय क्या है

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

मूल पूरे समुच्चय की रक्षा करता है

बाहरी कॉल करने वाले कभी भी आंतरिक सदस्यों को सीधे नहीं छूते। कोई LineItem जोड़ने के लिए आप मूल ऑब्जेक्ट की एक विधि को कॉल करते हैं, जो सत्यापन करती है और संगति बनाए रखती है (कुल योग, सीमाएँ)। इससे अपरिवर्तनीय शर्तें एक ही स्थान पर बनी रहती हैं।

<?php
final class LineItem {
    public function __construct(
        public readonly string $sku,
        public readonly int $qty,
        public readonly int $unitCents
    ) {}
    public function subtotal(): int { return $this->qty * $this->unitCents; }
}

final class Order { // Aggregate Root
    /** @var LineItem[] */
    private array $items = [];
    public function __construct(public readonly string $id) {}

    public function addItem(string $sku, int $qty, int $unitCents): void {
        if ($qty < 1) { throw new DomainException('qty must be >= 1'); }
        $this->items[] = new LineItem($sku, $qty, $unitCents);
    }
    public function total(): int {
        return array_sum(array_map(fn(LineItem $i) => $i->subtotal(), $this->items));
    }
}
$o = new Order('o1');
$o->addItem('A', 2, 500);
$o->addItem('B', 1, 300);
echo $o->total(), PHP_EOL; // 1300

छोटे समुच्चयों का अभिकल्पन

एक सामान्य गलती समुच्चयों को बहुत बड़ा बना देना है (ऐसा Order जो पूरे Customer ग्राफ़ का भी स्वामी हो)। सामान्य नियम:

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

पहचान से संदर्भ देना

आदेश में Customer इकाई नहीं, बल्कि customerId मान-वस्तु रखी जाती है। इससे सुसंगति की सीमा सघन रहती है और विशाल वस्तु-ग्राफ़ लाने से बचा जा सकता है। समुच्चयों के बीच सुसंगति अंततः स्थापित होती है और इसे एक बहुत बड़े लेन-देन के बजाय घटनाओं से संभाला जाता है।

<?php
final class CustomerId {
    public function __construct(public readonly string $value) {}
}
final class Order {
    public function __construct(
        public readonly string $id,
        public readonly CustomerId $customerId // reference, not object
    ) {}
}
$order = new Order('o1', new CustomerId('cus_99'));
echo $order->customerId->value, PHP_EOL;

भंडार का अनुबंध

भंडार समुच्चय-मूलों के स्मृति-आधारित संग्रह का आभास देता है। क्षेत्र केवल अंतरफलक पर निर्भर करता है; कार्यान्वयन (Doctrine, PDO, स्मृति-आधारित) आधारभूत संरचना परत में रहता है। भंडार पूरे समुच्चयों के साथ काम करते हैं, कभी आंशिक पंक्तियों के साथ नहीं।

<?php
interface OrderRepository {
    public function ofId(string $id): ?Order;
    public function save(Order $order): void;
    public function nextIdentity(): string;
}

स्मृति-आधारित कार्यान्वयन

स्मृति-आधारित भंडार तेज़, आँकड़ा-भंडार-रहित इकाई परीक्षणों के लिए अत्यंत उपयोगी है। चूँकि क्षेत्र अंतरफलक पर निर्भर करता है, आप कार्यान्वयनों को स्वतंत्र रूप से बदल सकते हैं (निर्भरता उत्क्रमण का व्यावहारिक उदाहरण)।

<?php
interface OrderRepository {
    public function ofId(string $id): ?object;
    public function save(object $order): void;
    public function nextIdentity(): string;
}
final class Order { public function __construct(public readonly string $id) {} }

final class InMemoryOrderRepository implements OrderRepository {
    private array $store = [];
    public function ofId(string $id): ?object { return $this->store[$id] ?? null; }
    public function save(object $order): void { $this->store[$order->id] = $order; }
    public function nextIdentity(): string { return 'o_' . bin2hex(random_bytes(4)); }
}
$repo = new InMemoryOrderRepository();
$repo->save(new Order('o1'));
var_dump($repo->ofId('o1') !== null);

भंडार DAO नहीं है

भंडार कोई सामान्य सृजन-पठन-परिवर्तन-विलोपन DAO नहीं है। यह क्षेत्र के अर्थ वाली प्रश्न-विधियाँ (findOverdueOrders()) उपलब्ध कराता है और उनकी अपरिवर्तनीय शर्तों को अक्षुण्ण रखते हुए पूरे समुच्चयों का पुनर्गठन करता है। यह SQL और वस्तु-संबंध मानचित्रक के विवरणों को जानबूझकर छिपाता है, ताकि क्षेत्र स्थायी भंडारण से अनभिज्ञ रहे। क्षेत्र में प्रश्न-निर्माताओं या save($anyEntity) जैसी सामान्य विधियों को आने न दें।

जटिल निर्माण के लिए निर्माणक

जब किसी समुच्चय के निर्माण में वास्तविक तर्क शामिल हो—पहचान उत्पन्न करना, मान-वस्तुओं को जोड़ना, निर्माण-समय की अपरिवर्तनीय शर्तें लागू करना—तो उसे किसी निर्माणक में ले जाइए (किसी समर्पित वर्ग या स्थैतिक नामित निर्माता में)। इससे इकाई की निर्माता-विधि स्पष्ट रहती है और मान्य निर्माण के नियम एक ही स्थान पर केंद्रित होते हैं।

<?php
final class Order {
    private function __construct(
        public readonly string $id,
        public readonly string $customerId
    ) {}
    public static function place(string $customerId): self {
        if ($customerId === '') { throw new DomainException('customer required'); }
        return new self('o_' . bin2hex(random_bytes(4)), $customerId);
    }
}
$order = Order::place('cus_1');
echo $order->id, PHP_EOL;

ये एक साथ कैसे काम करते हैं

किसी अनुप्रयोग सेवा का सामान्य प्रवाह:

  • कोई निर्माणक (या नामित निर्माता) मान्य समुच्चय बनाता है।
  • समुच्चय-मूल की विधियाँ उपयोग के दौरान अपरिवर्तनीय शर्तें लागू करती हैं।
  • कोई भंडार पूरे समुच्चय को स्थायी रूप से सहेजता है और बाद में उसका पुनर्गठन करता है।

अनुप्रयोग सेवा प्रत्येक समुच्चय के लिए एक लेन-देन के भीतर इनका समन्वय करती है और केवल अंतरफलक पर निर्भर रहती है।

पूरे समुच्चय की अपरिवर्तनीय शर्त लागू करना

मूल का वास्तविक मूल्य उन अपरिवर्तनीय शर्तों को लागू करने में है, जो कई सदस्यों तक फैली होती हैं। यहाँ आदेश किसी पंक्ति-वस्तु को तब अस्वीकार करता है, जब उससे कुल योग ऋण-सीमा से अधिक हो जाए—यह ऐसा नियम है जिसे कोई अकेली LineItem स्वयं लागू नहीं कर सकती। सभी बदलाव मूल के माध्यम से होने के कारण इस नियम को कभी दरकिनार नहीं किया जा सकता।

<?php
final class Order {
    private array $items = [];
    public function __construct(
        public readonly string $id,
        private int $creditLimitCents
    ) {}
    public function addItem(int $cents): void {
        if ($this->total() + $cents > $this->creditLimitCents) {
            throw new DomainException('Exceeds credit limit');
        }
        $this->items[] = $cents;
    }
    public function total(): int { return array_sum($this->items); }
}
$o = new Order('o1', 1000);
$o->addItem(600);
try { $o->addItem(600); } catch (DomainException $e) { echo $e->getMessage(), PHP_EOL; }
echo $o->total(), PHP_EOL; // 600

त्वरित जाँच

समुच्चय का अभिकल्पन।

पुनरावलोकन

आपने अपरिवर्तनीय शर्तों की रक्षा करना और साफ़-सुथरे ढंग से स्थायी रूप से सहेजना सीखा। समुच्चय सुसंगति और लेन-देन की सीमा बनाते हैं, केवल अपने मूल के माध्यम से बदले जाते हैं और अन्य समुच्चयों का संदर्भ पहचान से देकर छोटे रखे जाते हैं। भंडार क्षेत्रीय अंतरफलक के पीछे समुच्चय-मूलों को संग्रह के रूप में प्रस्तुत करते हैं, वस्तु-संबंध मानचित्रक और SQL को छिपाते हैं तथा स्मृति-आधारित परीक्षण-प्रतिरूप संभव बनाते हैं। निर्माणक जटिल और अपरिवर्तनीय शर्तें लागू करने वाले निर्माण को एक ही स्थान पर केंद्रित करते हैं। साथ मिलकर ये आपके क्षेत्रीय मॉडल को सुसंगत और स्थायी भंडारण से अनभिज्ञ रखते हैं।

शुरुआत निःशुल्क

एआई शिक्षक के साथ PHP सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
49
पाठ
195

अक्सर पूछे जाने वाले प्रश्न

क्या “एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी” पाठ निःशुल्क है?

हाँ—“एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और PHP Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी” में मैं क्या सीखूँगा?

एग्रीगेट से इनवेरिएंट सुरक्षित करें और उन्हें सुव्यवस्थित ढंग से स्थायी करें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ PHP Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या PHP Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर PHP Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस PHP Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर PHP Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. DDD के आधारभूत घटक: एंटिटी और वैल्यू ऑब्जेक्ट
  2. एग्रीगेट, रिपॉज़िटरी और फ़ैक्टरी
  3. डोमेन इवेंट और डोमेन सर्विस
  4. बाउंडेड कॉन्टेक्स्ट और कॉन्टेक्स्ट मैपिंग
← PHP Academy पर वापस जाएँ