2009-03-02 14 views
9

मैं ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के लिए अपेक्षाकृत नया हूं। मैं अवधारणाओं को काफी समझता हूं, लेकिन व्यावहारिक रूप से बोल रहा हूं, मुझे अपने ज़ेंड फ्रेमवर्क अनुप्रयोगों में मॉडल का सबसे अच्छा उपयोग करने के बारे में जानकारी खोजने में वास्तव में कठिन समय है।ज़ेंड फ्रेमवर्क: मॉडल और दृश्यों का उपयोग, सर्वोत्तम प्रथाओं

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

मेरी नियंत्रक में:

$object = new Object(); 
$object->setName('Foo Bar'); 
$this->view->object = $object; 

मेरे विचार टेम्पलेट में:

<h2><?= $this->object->getName() ?></h2> 

मैं डॉन ' वास्तव में मेरे दृश्य टेम्पलेट्स में फ़ंक्शंस कॉल करना पसंद नहीं है लेकिन मुझे ऐसा करने का बेहतर तरीका नहीं पता है। मैं अपने मॉडल के सदस्यों को सार्वजनिक नहीं करना चाहते, लेकिन मैं मूल रूप से एक ही परिणाम हासिल करना चाहते हैं:

<h2><?= $this->object->name ?></h2> 

मैं अपने नियंत्रक मॉडल के बारे में सब कुछ पता होने के सभी काम करने के लिए नहीं करना चाहते हैं:

$object = new Object(); 
$object->setName('Foo Bar'); 
$this->view->object = $object; 
$this->view->object->name = $object->getName(); 

ज़ेंड फ्रेमवर्क में मॉडल का उपयोग करने का सबसे अच्छा अभ्यास क्या है? क्या कोई भी ऐसे ट्यूटोरियल की सिफारिश कर सकता है जो मुझे ज़ेन फ्रेमवर्क में इस मॉडल/व्यू दुविधा को समझने में मदद करेगा?

उत्तर

4

PHP में जादू __set और __get विधियों का उपयोग करना एक संभावना है।मैं अपने सार मॉडल वर्ग के भीतर तो जैसे उन्हें इस्तेमाल:

abstract class Model_Abstract 
{ 
    protected $_data; 

    // Private Data Members assigned to protected $_data 
    public function __construct($data = null) 
    { 
     // Makes it so that I can pass in an associative array as well as 
     // an StdObject. 
     if(!is_object($data)) { 
      $data = (object) $data; 
     } 

     $this->_data = $data; 

    } 

    public function __get($key) 
    { 
     if (method_exists($this, '_get' . ucfirst($key))) { 
      $method = '_get' . ucfirst($key); 
      return $this->$method();    
     } 
     else { 
      return $this->_data->$key; 
     } 
    } 

    public function __set($key, $val) 
    { 
     if (method_exists($this, '_set' . ucfirst($key))) { 
      $method = '_set' . ucfirst($key); 
      return $this->$method($val);    
     } 
     else { 
      $this->_data->$key = $val; 
      return $this->_data->$key; 
     } 
    } 
} 


class Model_User extends Model_Abstract 
{ 
    //Example overriding method for the property firstName in the $_data collection. 
    protected function _getFirstName() 
    { 
     // Do some special processing and then output the first name. 
    } 
} 

यह बात करता है, ताकि आप के रूप में आवश्यक गुणों के लिए getters और setters निर्दिष्ट कर सकते हैं, लेकिन यह करता है, ताकि आप हर प्रॉपर्टी के लिए बॉयलरप्लेट कार्यों को परिभाषित करने की जरूरत नहीं , केवल वे मूल्य जहां आप मूल्य वापस करने से पहले इस पर कुछ प्रकार की प्रसंस्करण करना चाहते हैं। उदाहरण के लिए, मैं उपयोगकर्ताओं के लिए एक अधिक कॉम्पैक्ट और पठनीय प्रारूप में आईएसओ अनुपालन तिथियों (जैसा कि MySQL में संग्रहीत) को बदलने के लिए कई स्थानों में कार्यक्षमता का उपयोग करता हूं।

जहां तक ​​आपके नियंत्रक में स्थान रखना है, मैं आपके नियंत्रक के भीतर क्या हैंडलिंग के बारे में कुछ विशिष्ट प्रतिक्रिया के लिए this post पर देखने की अनुशंसा करता हूं।

कुछ लोगों का मानना ​​है कि उनके पास एक सहायक होगा जो स्वचालित रूप से दृश्यों को मॉडल में लोड करता है और नियंत्रक को पूरी तरह से स्कर्ट करता है। व्यक्तिगत रूप से मैं कहूंगा कि ज़ेंड फ्रेमवर्क और PHP के संदर्भ में यह नियंत्रक से दृश्य में मॉडल को पारित करने के लिए बहुत सारी समझ में आता है क्योंकि दृश्य में मॉडल की स्थिति अक्सर अनुरोध से क्या होती है (जिसे निश्चित रूप से संभाला जाना चाहिए) पर निर्भर करता है नियंत्रक में)।

अपडेट: टिप्पणियों में आलोचनाओं के अनुसार, एक बात जो मैं इंगित करता हूं वह यह है कि आपकी डेटाबेस एक्सेस लेयर और डोमेन (या मॉडल) परत वास्तव में दो अलग-अलग चीजें हैं, हालांकि सक्रिय रिकॉर्ड के साथ वे एक साथ मिश्रित होते हैं । मैंने कुछ समय पहले this question से पूछा और इस मामले पर कुछ उपयोगी प्रतिक्रिया प्राप्त की। जो भी आप मॉडल के साथ करने का निर्णय लेते हैं, आप मॉडल के डेटा कहां से आते हैं, इस पर ध्यान दिए बिना आप सभी डोमेन ऑब्जेक्ट्स के लिए एक सतत API प्रदान करना चाहेंगे।

मुझे लगता है कि सैम के उत्तर द्वारा प्रदान किया गया एक लाभ यह है कि यह एक या अधिक डोमेन ऑब्जेक्ट्स से दृश्य ऑब्जेक्ट में गुण/फ़ंक्शन रिटर्न मानों को सीधे मैप करने की क्षमता प्रदान करता है। सैद्धांतिक रूप से दृश्य के भीतर उपयोग तो इस तरह दिखता है:

// Mapped from Model_User::_data->last_name and Model_User::_data->first_name 
$this->name 
+1

यह वास्तव में चीजों को करने का एक खराब तरीका है। न केवल आप सभी गुणों के लिए मनमाने ढंग से पहुंच प्रदान करते हैं, भले ही वे एक हैं (एक) एक फॉर्म से/से क्रमबद्ध होना चाहिए या नहीं, यह मॉडल को मैपिंग की अवधारणा के साथ भी अधिभारित करता है, जिसे वास्तव में पूछा जाता था। – Saem

+0

मॉडल में फॉर्म तर्क डालने से दृश्य और मॉडल मिल जाता है जो कि खराब रूप भी है। और जैसा कि मैंने पहले ही कहा है, डिफ़ॉल्ट व्यवहार को ओवरराइड करना बहुत आसान है और बेवकूफ बॉयलरप्लेट गेटर्स और सेटर्स बनाने की आवश्यकता से बचाता है। –

+0

और यदि आप Zend_Db_Table_Row क्लास को देखते हैं तो आप पाएंगे कि ज़ेंड वास्तव में फ़ील्ड और फ़ील्ड से उनके मूल्यों का पर्दाफाश करने के लिए एक समान सिद्धांत का उपयोग करता है। –

3

यदि केवल अन्य डेवलपर टेम्पलेट्स के साथ काम करने जा रहे हैं, तो मैं बस मॉडल में गुजरने की अनुशंसा करता हूं। एमवीसी Understanding Model-View-Controller

3

पर जेफ एटवुड पोस्ट का एक लिंक यहां दिया गया है, यह विशेष रूप से ज़ेंड फ्रेमवर्क की दिशा में तैयार नहीं है, लेकिन समस्या मेरे दिमाग में सामान्य है।

ऐसा लगता है कि आप कंट्रोलर के अंदर मॉडल को हार्ड वायरिंग के बजाय सही रास्ते पर हैं। यदि आप एक टन मॉडल का मानचित्रण कर रहे हैं, या उसी मॉडल को बार-बार मैप करना चाहते हैं, तो आप उस सार को विशेष रूप से महत्वपूर्ण मानेंगे।

मैपिंग फ़ंक्शंस का एक गुच्छा लिखना कुछ आसान होगा, जो ठीक होगा अगर आप से बच रहे थे, वही चीज़ मैपिंग कर रहा है।

यदि आप एक अधिक सामान्य समाधान चाहते थे, तो उस बॉयलर प्लेट कोड को लिखने से बचने और चीजों को और अधिक डीआरवाई रखने से संबोधित किया गया, तो मैं एक मैपर वर्ग बनाने का सुझाव देता हूं।

आप एक ViewModelMapper बना सकते हैं, जो एक मॉडल, या कुछ मॉडल लेगा और उन्हें दृश्य में मानचित्रित करेगा।

class ViewModelMapper 
{ 
    public function __construct($view) 
    { 
     //set the properties 
    } 

    public function addModel($model, $overrideViewProperty = null) 
    { 
     //add the model to the list of models to map, use the view's property 
     // name to figure out what to map it to? Allow for an override just in case. 
    } 

    public function getMappedView() 
    { 
     //take the view, map all the models 
    } 
} 

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

+0

कृपया एक प्रासंगिक उदाहरण प्रदान करें जो इस मैपर वर्ग का उपयोग करता है। अभी तक मैं देखता हूं कि मॉडल को और अधिक जटिल में जोड़ने के लिए एक तरीका है। –

1

मॉडल वास्तुकला, read this post पर एक अच्छा पढ़ा है। यह विशेष रूप से दृश्य के बारे में बात नहीं करता है, लेकिन यह निश्चित रूप से पढ़ने लायक है।

मैंने अपने मॉडल में getViewClass() फ़ंक्शन जोड़ना समाप्त कर दिया। नियंत्रक इस फ़ंक्शन को संरक्षित वेरिएबल्स प्राप्त करने के लिए कहता है, जो अन्यथा तक पहुंच नहीं पाएंगे, और दृश्य को किसी भी गेटर्स को कॉल करने की चिंता करने की आवश्यकता नहीं है।

//controller 
$object = new Object(); 
$object->setName('Foo Bar'); 
$this->view->object = $object->getViewClass(); 

//view template 
<h2><?= $this->object->name ?></h2> 

मुझे नहीं पता कि ज़ेंड फ्रेमवर्क में नौकरी पाने का बेहतर तरीका है, लेकिन यह एक समाधान है।

संबंधित मुद्दे