Kodokon kodokon.com

आधुनिक OOP: क्लास, प्रमोटेड प्रॉपर्टी, विज़िबिलिटी

मुहावरेदार PHP 8 क्लास लिखें: प्रॉपर्टी प्रमोशन, readonly, नेम्ड कंस्ट्रक्टर और अपरिवर्तनीय वैल्यू ऑब्जेक्ट।

9 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

आप लंबे समय से क्लास लिख रहे हैं, लेकिन PHP 8 ने कई आदतों को अप्रचलित बना दिया है। सबसे स्पष्ट है: कंस्ट्रक्टर में प्रॉपर्टी प्रमोशन। किसी कंस्ट्रक्टर पैरामीटर के आगे एक विज़िबिलिटी कीवर्ड (private, protected, public) जोड़ने से प्रॉपर्टी बन जाती है और एक ही चरण में उसे असाइन भी कर दिया जाता है। पुरानी शैली के तीन दोहराव वाले ब्लॉक - घोषणा, पैरामीटर, असाइनमेंट - मिलकर एक में सिमट जाते हैं।

PHP
<?php

declare(strict_types=1);

class LegacyProduct
{
    private string $name;
    private int $priceCents;

    public function __construct(
        string $name,
        int $priceCents,
    ) {
        $this->name = $name;
        $this->priceCents = $priceCents;
    }
}

final class Product
{
    public function __construct(
        private string $name,
        private int $priceCents,
    ) {
    }

    public function label(): string
    {
        return sprintf(
            '%s (%.2f EUR)',
            $this->name,
            $this->priceCents / 100,
        );
    }
}

$product = new Product('Keyboard', 4990);
echo $product->label();
पहले / बाद में: प्रमोशन सारा बॉयलरप्लेट असाइनमेंट कोड हटा देता है।

एनकैप्सुलेशन के लिए विज़िबिलिटी आपका पहला औज़ार बनी रहती है: डिफ़ॉल्ट रूप से private, protected केवल तब जब किसी चाइल्ड क्लास को पहुँच चाहिए, और public अंतिम उपाय के रूप में। PHP 8.1 से, readonly एक और मज़बूत गारंटी जोड़ता है: प्रॉपर्टी को केवल एक बार लिखा जा सकता है, और वह भी उसी क्लास के दायरे के भीतर से जो इसे घोषित करती है। प्रमोशन के साथ मिलाकर, यह कुछ ही पंक्तियों में अपरिवर्तनीय वैल्यू ऑब्जेक्ट बनाता है: कोई भी "बदलाव" एक नया इंस्टेंस लौटाता है, जिससे साझा साइड इफेक्ट समाप्त हो जाते हैं।

PHP
<?php

declare(strict_types=1);

final class Money
{
    public function __construct(
        public readonly int $amount,
        public readonly string $currency,
    ) {
    }

    public function add(Money $other): self
    {
        if ($other->currency !== $this->currency) {
            throw new InvalidArgumentException(
                'Currency mismatch'
            );
        }

        return new self(
            $this->amount + $other->amount,
            $this->currency,
        );
    }
}

$total = (new Money(500, 'EUR'))
    ->add(new Money(250, 'EUR'));

echo $total->amount;
अपरिवर्तनीय वैल्यू ऑब्जेक्ट: add() एक नया इंस्टेंस लौटाता है।

मेथड की तरफ, अनुभवी डेवलपरों के बीच दो पैटर्न प्रभावी हैं। नेम्ड कंस्ट्रक्टर: एक private कंस्ट्रक्टर के साथ स्टैटिक फ़ैक्ट्री जोड़ने से हर मंशा स्पष्ट हो जाती है और असंगत इंस्टैंशिएशन पर रोक लग जाती है। फ़्लुएंट इंटरफ़ेस: $this (परिवर्तनीय) या new self(...) (अपरिवर्तनीय) लौटाने से आप कॉल को शृंखलाबद्ध कर सकते हैं। इसका समझौता सर्वविदित है: अपरिवर्तनीय संस्करण अधिक सुरक्षित है लेकिन हर कॉल पर एक ऑब्जेक्ट आवंटित करता है - लगभग हर जगह नगण्य, पर किसी हॉट लूप में मापने योग्य।

PHP
<?php

declare(strict_types=1);

final class User
{
    private function __construct(
        public readonly string $email,
        public readonly string $role,
    ) {
    }

    public static function admin(string $email): self
    {
        return new self($email, 'admin');
    }

    public static function member(string $email): self
    {
        return new self($email, 'member');
    }
}

$user = User::admin('lea@example.com');
echo $user->role;
प्राइवेट कंस्ट्रक्टर + स्टैटिक फ़ैक्ट्री: केवल वैध स्थितियाँ ही बनाई जा सकती हैं।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. PHP 8 कंस्ट्रक्टर में प्रॉपर्टी प्रमोशन क्या करता है?
    • यह स्वतः हर प्रॉपर्टी को public बना देता है
    • यह प्रॉपर्टी घोषित करता है और उसे पैरामीटर से एक ही चरण में असाइन कर देता है
    • यह हर प्रॉपर्टी के लिए एक्सेसर (getter) उत्पन्न करता है
    • यह प्रॉपर्टी को क्लास कॉन्स्टेंट में बदल देता है
  2. किसी readonly प्रॉपर्टी को कब लिखा जा सकता है?
    • कभी नहीं: इसे घोषणा के समय ही एक डिफ़ॉल्ट वैल्यू मिलनी चाहिए
    • ठीक एक बार, उसी क्लास के दायरे के भीतर से जो इसे घोषित करती है
    • किसी भी समय, बशर्ते लेखन स्वयं क्लास से आता हो
  3. ऐसी प्रॉपर्टी के लिए कौन सी विज़िबिलिटी चुननी चाहिए जिसका उपयोग केवल क्लास और उसकी चाइल्ड क्लास को करना चाहिए?
    • public
    • protected
    • private