2009-03-02 31 views
9

Tôi khá mới đối với Lập trình hướng đối tượng. Tôi hiểu khá nhiều về các khái niệm, nhưng thực tế nói, tôi đang có một thời gian thực sự khó tìm kiếm thông tin về cách sử dụng tốt nhất Các mô hình trong các ứng dụng Zend Framework của tôi.Zend Framework: Sử dụng Mô hình và Chế độ xem, các phương pháp hay nhất

Cụ thể, tôi có một Mô hình (không mở rộng bất kỳ thứ gì) không sử dụng Bảng cơ sở dữ liệu. Nó sử dụng getters và setters để truy cập các thành viên được bảo vệ của nó. Tôi thấy mình đang phải vật lộn với cách hiển thị tốt nhất mô hình này trong khung cảnh. Tôi không muốn logic trong xem mẫu của tôi, nhưng tôi thấy mình trong tình huống sau đây:

Trong điều khiển của tôi:

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

Trong mẫu quan điểm của tôi:

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

I don' Tôi thực sự thích các chức năng gọi điện trong các mẫu xem của mình nhưng tôi không biết cách nào tốt hơn để làm điều này. Tôi không muốn các thành viên Mẫu của tôi để được công khai, nhưng tôi về cơ bản muốn đạt được kết quả tương tự:

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

Tôi không muốn điều khiển của tôi để làm tất cả những công việc vì phải biết mọi thứ về các mô hình:

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

Thực tiễn tốt nhất khi sử dụng các mô hình trong khung công tác Zend là gì? Bất cứ ai có thể khuyên bạn nên bất kỳ hướng dẫn mà có thể giúp tôi hiểu mô hình này/Xem tiến thoái lưỡng nan trong Zend Framework?

Trả lời

4

Một khả năng là sử dụng các phương pháp __set và __get ma thuật trong PHP.Tôi sử dụng chúng như vậy trong lớp mẫu trừu tượng của tôi:

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. 
    } 
} 

này làm cho nó để bạn có thể chỉ định getter và setter đối với tài sản khi cần thiết nhưng làm cho nó để bạn không cần phải xác định chức năng soạn sẵn cho mỗi tài sản , chỉ là những nơi bạn muốn thực hiện một số loại xử lý trên đó trước khi trả về giá trị. Ví dụ, tôi sử dụng chức năng ở một số nơi để thay đổi ngày tuân thủ ISO (như được lưu trữ trong MySQL) thành một định dạng nhỏ gọn và dễ đọc hơn cho người dùng.

Theo như những gì cần đặt trong bộ điều khiển của bạn, tôi khuyên bạn nên xem this post để biết một số phản hồi cụ thể về cách xử lý đặt trong bộ điều khiển của bạn.

Một số người cảm thấy rằng họ muốn có người trợ giúp tự động tải các mô hình vào chế độ xem và điều chỉnh bộ điều khiển hoàn toàn. Cá nhân tôi sẽ nói rằng trong ngữ cảnh của khung công tác Zend và PHP, nó có ý nghĩa rất nhiều khi chuyển mô hình vào khung nhìn từ bộ điều khiển vì trạng thái của các mô hình trong khung nhìn thường phụ thuộc vào những gì đến từ yêu cầu. trong bộ điều khiển).

Cập nhật: Theo những lời chỉ trích trong nhận xét, một điều tôi chỉ ra là lớp truy cập cơ sở dữ liệu và lớp (hoặc mô hình) thực sự là hai điều khác nhau, mặc dù với Active Record chúng được pha trộn với nhau . Tôi đã yêu cầu this question một thời gian trở lại và đã nhận được một số phản hồi hữu ích về vấn đề này. Dù bạn quyết định làm gì với mô hình, bạn sẽ muốn cung cấp một API nhất quán cho tất cả các đối tượng miền bất kể nơi dữ liệu cho mô hình đến từ đâu.

Tôi giả sử rằng một lợi ích được cung cấp bởi câu trả lời của Saem là nó cung cấp khả năng ánh xạ trực tiếp các giá trị trả về thuộc tính/hàm từ một hoặc nhiều đối tượng miền cho đối tượng xem. Về mặt lý thuyết việc sử dụng trong tầm nhìn thì trông như thế này:

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

Đây thực sự là một cách làm việc kém. Bạn không chỉ cho phép truy cập tùy ý vào tất cả các thuộc tính, cho dù chúng là (un) được tuần tự hóa/từ một biểu mẫu hay không, nó cũng làm quá tải mô hình với khái niệm ánh xạ, đó là điều thực sự được yêu cầu. – Saem

+0

Đưa logic biểu mẫu vào mô hình kết hợp chế độ xem và mô hình cũng có dạng kém. Và như tôi đã nói, việc ghi đè hành vi mặc định là rất đơn giản và tránh sự cần thiết phải tạo ra các getters và các bộ định vị boilerplate ngu ngốc. –

+0

Và nếu bạn nhìn vào lớp Zend_Db_Table_Row bạn sẽ thấy rằng Zend thực sự sử dụng một nguyên tắc tương tự để trưng ra các trường và giá trị của chúng từ các bảng. –

3

Nếu chỉ các nhà phát triển khác đang làm việc với các mẫu, tôi khuyên bạn chỉ nên chuyển sang các mô hình. Đây là liên kết tới bài đăng của Jeff Atwood trên MVC Understanding Model-View-Controller

3

Điều này không đặc biệt hướng tới khuôn khổ zend, nhưng vấn đề là khá chung chung, trong tâm trí của tôi.

Có vẻ như bạn đang đi đúng hướng, thay vì dây cứng mô hình đến chế độ xem, bên trong bộ điều khiển. Bạn thà có sự trừu tượng đó, đặc biệt quan trọng nếu bạn đang lập bản đồ một tấn các mô hình, hoặc lập bản đồ cùng một mô hình lặp đi lặp lại.

Điều gì đó đơn giản là viết một loạt các hàm ánh xạ, điều này sẽ ổn nếu tất cả những gì bạn tránh là ánh xạ cùng một thứ.

Nếu bạn muốn có giải pháp tổng quát hơn, giải pháp đó cũng tránh được việc viết mã đĩa nồi hơi và giữ cho mọi thứ trở nên SẠCH hơn, tôi khuyên bạn nên tạo một lớp bản đồ.

Bạn có thể tạo một ViewModelMapper, mô hình này sẽ lấy một mô hình hoặc một vài mô hình và ánh xạ chúng vào chế độ xem.

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 
    } 
} 

Bạn có thể sau đó trường hợp này trên bộ điều khiển của bạn, và thiết lập ánh xạ, vì vậy bộ điều khiển kiểm soát bản đồ vẫn còn, nhưng tất cả các tấm lò hơi và mã hóa logic là tập trung, cho tất cả các bản đồ điều khiển, trừ các trường hợp ngoại lệ hiếm .

+0

Vui lòng cung cấp ví dụ có liên quan sử dụng lớp Mapper này. Tính đến thời điểm hiện tại, tất cả những gì tôi thấy là cách để thêm Mô hình vào Chế độ xem phức tạp hơn. –

1

Đối với một đọc tốt về kiến ​​trúc mô hình, read this post. Nó không cụ thể nói về quan điểm, nhưng nó chắc chắn đáng đọc.

Tôi đã kết thúc việc thêm chức năng getViewClass() vào các kiểu máy của mình. Bộ điều khiển gọi hàm này để nhận các biến được bảo vệ mà nó sẽ không có quyền truy cập vào, và khung nhìn không phải lo lắng về việc gọi bất kỳ getters nào.

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

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

Tôi không biết nếu có cách nào tốt hơn để hoàn thành công việc trong khung công tác Zend, nhưng đây là một giải pháp.

Các vấn đề liên quan