2013-06-24 3 views
0

Я создаю свою собственную инфраструктуру MVC, просто чтобы узнать что-то новое и в последнее время столкнулся с этой проблемой. Допустим, у меня есть, как это:Создание класса со многими параметрами

Class Post extends \application\BaseClass 
{ 
    private $objPostDetail = null; 
    private $objAuthor = null 
    private $objCategory = null; 
    private $objType = null; 
    private $objTitlePicture = null; 

    public function __construct(PostDetail $objPostDetail, 
           Author $objAuthor, 
           Category $objCategory, 
           Type $objType, 
           TitlePicture $objTitlePicture) 
    { 
     $this->objPostDetail = $objPostDetail; 
     $this->objAuthor = $objAuthor; 
     $this->objCategory = $objCategory; 
     $this->objType = $objType; 
     $this->objTitlePicture = $objTitlePicture; 
    } 
} 

Тогда некоторые объекты, используемые в constuctor также может быть Comlex создать. Я получаю данные для него из класса PostDAO, который возвращает массив данных. Теперь проблема заключается в том, как создать новый экземпляр этого класса, поскольку он может быть во многих местах приложения. Я думаю, что создать везде $ objAuthor, затем $ objCategory и т. Д., Чтобы наконец создать $ objPost, не очень хорошо. Так что я создал то, что я думаю, что можно назвать завод:

Class PostFactory extends \application\BaseFactory 
{ 
    private $arrData = null; 
    private $objPostDetail = null; 
    private $objCategory = null; 
    private $objType = null; 
    private $objTitlePicture = null; 

    public function __construct($arrData) 
    { 
     $this->arrData = $arrData; 
    } 

    public function build() 
    { 
     $this->objPostDetail = $this->buildPostDetail(); 
     $this->objCategory = $this->buildCategory(); 
     $this->objType = $this->buildType(); 
     $this->objTitlePicture = $this->buildTitlePicture(); 

     return $this->buildPost(); 
    } 

    private function buildPostDetail() 
    { 
     $objPostDetail = new \includes\classes\factories\PostDetailFactory($this->arrData); 
     return $objPostDetail->build(); 
    } 

    private function buildCategory() 
    { 
     $objCategory = new \includes\classes\factories\CategoryFactory($this->arrData); 
     return $objCategory->build(); 
    } 

    private function buildType() 
    { 
     $objType = new \includes\classes\factories\TypeFactory($this->arrData); 
     return $objType->build(); 
    } 

    private function buildTitlePicture() 
    { 
     $objTitlePicture = new \includes\classes\factories\TitlePictureFactory($this->arrData); 
     return $objTitlePicture->build(); 
    } 

    private function buildPost() 
    { 
     return new \includes\classes\Post($this->objPostDetail, $this->objCategory, 
         $this->objType, $this->objTitlePicture); 
    } 
} 

Это работает хорошо, но мне не нравится, что у меня есть в два раза больше классов, и я не знаю, какие параметры мне нужно сделать для инстанцирования Post поскольку я передаю массив классу Factory (потому что я хочу избежать многих параметров в конструкторе). Итак, мой вопрос - как лучше всего создать экземпляр класса?

Заранее благодарим за любую помощь.

ответ

1

Если вы хотите создать свою собственную инфраструктуру MVC, я настоятельно рекомендую начать с своего рода «Контейнера», который содержит экземпляры служебных классов (классы, которые нужно только инициализировать один раз, например Request или Response).

Используйте классы отражения, чтобы автоматически вводить параметры, необходимые конструктору, итерации по аргументам функции конструктора.

См. Следующий пример идеи, которую я обычно использую. Он очень надежный и достаточно быстрый. Если ваша структура имеет много разных классов, и вы сильно зависите от этой функциональности, я настоятельно рекомендую реализовать некоторый способ кэширования списков параметров из классов отражения.

<?php 
class SomeClass 
{ 
    public function __construct(Request $request, Response $response, $title = '') 
    { 
     echo get_class($request); 
     // will output "Request" 

     echo $title; 
     // will output "Hello World" 
    } 
} 

// This function will handle the dynamic dependency injection to make sure the constructor gets the arguments passed that it needs, with optional named arguments passing. 
$some_class = YourFrameworkDispatcherClass->createInstance('SomeClass', array('title' => 'Hello World')); 
?> 

Я действительно написал сообщение в блоге об этом в своем блоге. http://harold.info/engineering/php-dynamic-dependency-injection/

Я думаю, что это поможет вам справиться с этой структурной проблемой.

+0

Моя проблема заключается в том, как создать объект после получения данных из модели, я знаю, как передать его модели, потому что обычно это несколько параметров. – Petr

+0

Хорошо, тогда применяется то же самое решение. Вы уже знаете, что получаете взамен от модели. Используйте его в стиле имен, как описано в моем сообщении в блоге. Просто назовите аргументы конструктора так же, как и модель, и он будет автоматически передан конструктору;) – Harold