PHP में एक फैक्टरी डिजाइन पैटर्न क्या है?


88

यह मुझे भ्रमित करता है, सबसे सरल शब्दों में यह क्या करता है? बहाना आप अपनी माँ या किसी को समझा रहे हैं लगभग कृपया।


115
मेरी माँ वैसे भी इसे नहीं समझती ...
ब्रूनो रीस

6
@JasonDavis मैं आपके सवालों का जवाब देता रहता हूं ... मैं एक शिकारी की तरह महसूस करने लगा हूं।
टायलर कार्टर

जवाबों:


175

एक कारखाना एक वस्तु बनाता है। इसलिए, यदि आप निर्माण करना चाहते थे

 class A{
    public $classb;
    public $classc;
    public function __construct($classb, $classc)
    {
         $this->classb = $classb;
         $this->classc = $classc;
    }
  }

आप निम्न कोड को हर बार जब आप वस्तु बनाते हैं, पर भरोसा नहीं करना चाहेंगे

$obj = new ClassA(new ClassB, new Class C);

यही वह जगह है जहाँ कारखाना आएगा। हम अपने लिए देखभाल करने के लिए एक कारखाने को परिभाषित करते हैं:

class Factory{
    public function build()
    {
        $classc = $this->buildC();
        $classb = $this->buildB();
        return $this->buildA($classb, $classc);

    }

    public function buildA($classb, $classc)
    {
        return new ClassA($classb, $classc);
    }

    public function buildB()
    {
        return new ClassB;
    }

    public function buildC()
    {
        return new ClassC;
    }
}

अब हमें बस इतना करना है

$factory = new Factory;
$obj     = $factory->build();

असली फायदा तब है जब आप क्लास बदलना चाहते हैं। कहते हैं कि हम एक अलग वर्ग में उत्तीर्ण होना चाहते थे:

class Factory_New extends Factory{
    public function buildC(){
        return new ClassD;
    }
}

या एक नया ClassB:

class Factory_New2 extends Factory{
    public function buildB(){
        return new ClassE;
    }
}

अब हम वंशानुक्रम का उपयोग आसानी से संशोधित करने के लिए कर सकते हैं कि कक्षा कैसे बनाई जाती है, अलग-अलग वर्गों में सेट करने के लिए।

एक अच्छा उदाहरण यह उपयोगकर्ता वर्ग हो सकता है:

class User{
    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
}

इस वर्ग $dataमें वह वर्ग है जिसका उपयोग हम अपने डेटा को संग्रहीत करने के लिए करते हैं। अब इस वर्ग के लिए, हम कहते हैं कि हम अपने डेटा को संग्रहीत करने के लिए एक सत्र का उपयोग करते हैं। कारखाने इस तरह दिखेगा:

class Factory{
    public function build()
    {
        $data = $this->buildData();
        return $this->buildUser($data);
    }

    public function buildData()
    {
        return SessionObject();
    }

    public function buildUser($data)
    {
        return User($data);
    }
}

अब, इसके बजाय हम अपने सभी डेटा को डेटाबेस में संग्रहीत करना चाहते हैं, इसे बदलने के लिए वास्तव में सरल है:

class Factory_New extends Factory{
    public function buildData()
    {
        return DatabaseObject();
    }
}

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


3
वह बहुत टाइपिंग थी। अब मुझे किसी समय इसे अपनी विकि पर रखना होगा।
टायलर कार्टर

1
अच्छा और मददगार। आप को सलाम।
स्टेफगोसलिन

1
आपके कोड $obj = $factory->build();पर क्या अंतर / लाभ है $obj = new whateverClass();? इसके अलावा, एक अन्य वर्ग में (कहें क्लासज़) जो क्लासए के डेटा पर निर्भर करता है, जहां क्लासज़ में आप फ़ैक्टरी विधि का उपयोग करेंगे? आप अनिवार्य रूप से अभी भी एक वर्ग (क्लास) के भीतर एक वर्ग (क्लासज़) को इंस्टेंट कर रहे हैं, जिसका अर्थ है कोई परीक्षण नहीं। उदाहरण के लिए, फैक्ट्री newसिर्फ उपयोग करने के बजाय एक विधि के माध्यम से करने के लिए कोड का भार लगती है new
जेम्स

19

एक वास्तविक जीवन कारखाने की तरह, यह कुछ बनाता है और इसे वापस करता है।

कुछ इस तरह की कल्पना करो

$joe = new Joe();
$joe->say('hello');

या एक कारखाना विधि

Joe::Factory()->say('hello');

कारखाना विधि के कार्यान्वयन से एक नया उदाहरण बनेगा और इसे वापस किया जाएगा।


1
अच्छा उदाहरण, मुझे आश्चर्य होता है कि इस पैटर्न के लिए कार्यान्वयन कितने विविध हैं। जब मुझे वैधानिक रूप से कहा जाता है, तो मैं मान सकता हूं कि बाद में उसी उदाहरण का पुन: उपयोग करने के लिए कोई उदाहरण प्राप्त कर सकता है? यानी $ जो = जो :: फैक्टरी () -> कहना ('हैलो');
स्टेफगोसलिन

निश्चित रूप से 5.6 पर भी (नया जो ()) -> कह ('हैलो') कर सकते हैं;
पंचो

12

जब आप कई संसाधनों के साथ काम कर रहे होते हैं और उच्च स्तरीय अमूर्तता को लागू करना चाहते हैं तो फ़ैक्टरी डिज़ाइन पैटर्न बहुत अच्छा होता है।

आइए इसे अलग-अलग सेक्शन में तोड़ते हैं।

मान लीजिए कि आपको अमूर्तता को लागू करना है और आपकी कक्षा के उपयोगकर्ता को इस बात की परवाह करने की आवश्यकता नहीं है कि आपने कक्षा की परिभाषा में क्या लागू किया है।

उसे आपकी कक्षा के तरीकों के उपयोग के बारे में चिंता करने की ज़रूरत है।

उदा। आपके पास अपने प्रोजेक्ट के लिए दो डेटाबेस हैं

class MySQLConn {

        public function __construct() {
                echo "MySQL Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your mysql select query execute here" . PHP_EOL;
        }

}

class OracleConn {

        public function __construct() {
                echo "Oracle Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your oracle select query execute here" . PHP_EOL;
        }

}

आपका कारखाना वर्ग डेटाबेस कनेक्शन के लिए ऑब्जेक्ट के निर्माण का ध्यान रखेगा।

class DBFactory {

        public static function getConn($dbtype) {

                switch($dbtype) {
                        case "MySQL":
                                $dbobj = new MySQLConn();
                                break;
                        case "Oracle":
                                $dbobj = new OracleConn();
                                break;
                        default:
                                $dbobj = new MySQLConn();
                                break;
                }

                return $dbobj;
        }

}

उपयोगकर्ता को केवल डेटाबेस प्रकार का नाम पास करना होगा

$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();

आउटपुट:

MySQL Database Connection
Your mysql select query execute here

भविष्य में आपके पास अलग-अलग डेटाबेस हो सकते हैं, फिर आपको पूरे कोड को बदलने की आवश्यकता नहीं है केवल नए डेटाबेस प्रकार को पारित करने की आवश्यकता है और अन्य कोड बिना कोई बदलाव किए चलेंगे।

$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();

आउटपुट:

Oracle Database Connection
Your oracle select query execute here

आशा है कि यह मदद करेगा।


1

सामान्य तौर पर "फ़ैक्टरी" कुछ पैदा करता है: ऑब्जेक्ट-ओरिएंटेड-प्रोग्रामिंग के मामले में, एक "फ़ैक्टरी डिज़ाइन पैटर्न" वस्तुओं का उत्पादन करता है।

इससे कोई फर्क नहीं पड़ता कि यह PHP, C # या किसी अन्य Object-Orientated भाषा में है।


1

फ़ैक्टरी डिज़ाइन पैटर्न (फ़ैक्टरी पैटर्न) ढीली युग्मन के लिए है। कारखाने के अर्थ की तरह, अंतिम उपयोगकर्ता के लिए कारखाने का डेटा (डेटा का उत्पादन)। इस तरह, कारखाने डेटा के स्रोत और डेटा की प्रक्रिया के बीच तंग युग्मन को तोड़ते हैं।



0

यह उत्तर अन्य पोस्ट के संबंध में है जिसमें डैनियल व्हाइट ने कारखाने पैटर्न का उपयोग करके MySQL कनेक्शन बनाने के लिए कारखाने का उपयोग करने के लिए कहा था।

MySQL कनेक्शन के लिए मैं बल्कि सिंगलटन पैटर्न का उपयोग करूंगा क्योंकि आप डेटाबेस को एक्सेस करने के लिए उसी कनेक्शन का उपयोग करना चाहते हैं जो दूसरा नहीं बनाता है।


0

किसी वस्तु को त्वरित करने का क्लासिक तरीका है:

$Object=new ClassName();

PHP के पास सिंटैक्स का उपयोग करके चर नाम से एक वस्तु को गतिशील बनाने की क्षमता है:

$Object=new $classname;

जहाँ चर $ classname में वर्ग का नाम होता है, वह तुरंत शुरू करना चाहता है।

तो क्लासिक वस्तु फैक्टरिंग की तरह दिखेगा:

function getInstance($classname)
{
  if($classname==='Customer')
  {
    $Object=new Customer();
  }
  elseif($classname==='Product')
  {
    $Object=new Product();
  }
  return $Object;
}

और अगर आप getInstance ('उत्पाद') को कॉल करते हैं, तो यह फैक्ट्री प्रोडक्ट ऑब्जेक्ट को बनाएगी और लौटाएगी। अन्यथा यदि आप getInstance ('ग्राहक') को कॉल करते हैं, तो यह कारखाना फ़ंक्शन बनाता है और ग्राहक प्रकार ऑब्जेक्ट (ग्राहक () वर्ग से निर्मित) लौटाएगा।

इसके लिए किसी भी अधिक की आवश्यकता नहीं है, कोई व्यक्ति 'उत्पाद' या 'ग्राहक' (मौजूदा कक्षाओं के सटीक नाम) को गतिशील तात्कालिकता के लिए चर के मूल्य के रूप में भेज सकता है:

$classname='Product';
$Object1=new $classname; //this will instantiate new Product()

$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()

0

रिकॉर्ड के लिए, आसान शब्दों में, @Pindatjuh जैसे कारखाने ने कहा, एक वस्तु लौटाता है।

तो, एक निर्माता के साथ क्या अंतर है? (यह वही करता है)

  1. एक कंस्ट्रक्टर अपने स्वयं के उदाहरण का उपयोग करता है।
  2. कुछ ऐसा जो मैं चाहता हूं कि वह और अधिक उन्नत हो और मैं वस्तु को खिलाना नहीं चाहता (या निर्भरता जोड़ें)।
  3. जब प्रत्येक आवृत्ति बनाई जाती है, तो कंस्ट्रक्टर को कहा जाता है। कभी-कभी आप ऐसा नहीं चाहते हैं।

    उदाहरण के लिए, मान लें कि हर बार जब मैं कक्षा खाता का एक ऑब्जेक्ट बनाता हूं, तो मैं डेटाबेस से एक फ़ाइल पढ़ता हूं और इसे एक टेम्पलेट के रूप में उपयोग करता हूं।

निर्माणकर्ता का उपयोग करना:

class Account {
      var $user;
      var $pwd;
      var ...
      public __construct() {
         // here i read from the file
         // and many other stuff
      }
}

कारखाने का उपयोग:

class Account {
      var $user;
      var $pwd;
      var ...
}
class AccountFactory {
      public static Create() {
         $obj=new Account();
         // here we read the file and more stuff.
         return $obj;
      }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.