Kodokon kodokon.com

वंशानुक्रम, इंटरफ़ेस, ट्रेट और एब्स्ट्रैक्ट क्लास

हर एक के समझौतों को जानकर सही डिज़ाइन औज़ार चुनें - एक अनुबंध, एक एल्गोरिदम का ढाँचा, या क्षैतिज पुनः प्रयोग।

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

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

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

PHP
<?php

declare(strict_types=1);

abstract class Exporter
{
    public function export(array $rows): string
    {
        return $this->head() . $this->body($rows);
    }

    abstract protected function head(): string;

    abstract protected function body(
        array $rows
    ): string;
}

final class CsvExporter extends Exporter
{
    protected function head(): string
    {
        return "id;name\n";
    }

    protected function body(array $rows): string
    {
        $lines = array_map(
            fn (array $r): string => implode(';', $r),
            $rows,
        );

        return implode("\n", $lines);
    }
}

$csv = new CsvExporter();
echo $csv->export([[1, 'Ada'], [2, 'Linus']]);
टेम्पलेट मेथड: पैरेंट एल्गोरिदम तय करता है, बच्चे विवरण प्रदान करते हैं।

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

PHP
<?php

declare(strict_types=1);

interface Cache
{
    public function get(string $key): ?string;

    public function set(
        string $key,
        string $value
    ): void;
}

final class ArrayCache implements Cache
{
    private array $items = [];

    public function get(string $key): ?string
    {
        return $this->items[$key] ?? null;
    }

    public function set(
        string $key,
        string $value
    ): void {
        $this->items[$key] = $value;
    }
}

$cache = new ArrayCache();
$cache->set('lang', 'PHP');
echo $cache->get('lang');
क्लाइंट कोड Cache पर निर्भर करता है: कार्यान्वयन विनिमेय बना रहता है।

ट्रेट क्षैतिज साझाकरण की समस्या हल करते हैं: बिना किसी साझा पूर्वज वाली क्लासों में वही मेथड इंजेक्ट करना। जब दो ट्रेट एक ही नाम का मेथड प्रदान करते हैं, तो PHP आपके लिए चुनाव करने से इनकार कर देती है और एक स्पष्ट समाधान की माँग करती है: insteadof उस संस्करण को नामित करता है जिसे रखना है, और as एक उपनाम बनाता है ताकि दूसरा भी सुलभ बना रहे। यह जान-बूझकर वाचाल है - विरोध कोड में दिखता रहना चाहिए।

PHP
<?php

declare(strict_types=1);

trait FileLogger
{
    public function log(string $message): void
    {
        echo "[file] $message\n";
    }
}

trait AuditLogger
{
    public function log(string $message): void
    {
        echo "[audit] $message\n";
    }
}

final class PaymentService
{
    use FileLogger, AuditLogger {
        FileLogger::log insteadof AuditLogger;
        AuditLogger::log as audit;
    }
}

$service = new PaymentService();
$service->log('Payment received');
$service->audit('Payment received');
ट्रेट विरोध: insteadof निर्णय करता है, as एक उपनाम रखता है।

ज्ञान जांच

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

  1. एब्स्ट्रैक्ट क्लास पर इंटरफ़ेस का कौन सा निर्णायक लाभ है?
    • यह साझा प्रॉपर्टी रख सकता है
    • एक क्लास कई इंटरफ़ेस कार्यान्वित कर सकती है, पर केवल एक ही क्लास से वंशानुक्रम पा सकती है
    • इसके मेथड तेज़ चलते हैं
  2. एक ही क्लास द्वारा इस्तेमाल किए गए दो ट्रेट में से हर एक log() मेथड घोषित करता है। क्या होता है?
    • PHP पहले सूचीबद्ध ट्रेट के मेथड का उपयोग करती है
    • घातक त्रुटि, जब तक कि insteadof से स्पष्ट रूप से समाधान न किया जाए
    • PHP दोनों मेथड को एक में मिला देती है
  3. एब्स्ट्रैक्ट क्लास में ऐसा क्या हो सकता है जो इंटरफ़ेस में नहीं हो सकता?
    • कॉन्स्टेंट
    • प्रॉपर्टी और कार्यान्वित मेथड
    • पब्लिक मेथड सिग्नेचर