在运行时未知类类型时,使用带有控制反转的工厂方法

问题描述 投票:2回答:1

我有一个关于IOC的问题,当我不知道要在运行时实例化的类时。例如,我有几种类型的View类。 (HtmlView,CsvView,PDFView等)实现我的视图界面。我需要的视图类的类型由用户输入(DB中的字符串)决定。我倾向于使用具有make方法的ViewFactory类,问题是这将隐藏View依赖项,因为我只需要一个ViewFactory

   class ViewFactory{
        public function make($viewType){
              if($viewType == 'html'){
                 $view = new HtmlView();
              }
              // ...
              return $view   
        }
   } 

   class ReportGenerator{
           public function constructor(Array $data, ViewFactory $viewFactory, String $viewType ){
                 $this->data = $data;
                 $this->view = $viewFactory($viewType);
           }
           public function generate(){
                  return $this->view->render($this->data)
           }
   }   

在我看来,不清楚ReportGenerator依赖于基地ViewInterface。有没有更好的方法,不使用静态方法。

php oop design-patterns dependency-injection inversion-of-control
1个回答
0
投票
interface ViewInterface {

  public function render();
}

class HtmlView implements ViewInterface {

  const HTML_VIEW = 'html';

  public function render() {
    // TODO: Implement render() method.
  }
}

class AnotherView implements ViewInterface {

  const ANOTHER_VIEW = 'another';

  public function render() {
    // TODO: Implement render() method.
  }

}

class ViewFactory {

  public static function make($viewType) { // this could also be static
    // or use a construct, whichever strikes your fancy
    if ('html' == $viewType) { // fan of Yoda metod, I am
      $view = new HtmlView();
    }
    // ...
    return $view;
  }
}

class ReportGenerator {

  private $data;
  private $view;

  public function constructor(array $data, ViewInterface $view) {
    $this->data = $data;
    $this->view = $view;
  }

  public function generate() {
    return $this->view->render($this->data);

  }
}


$view = ViewFactory::make(HtmlView::HTML_VIEW);


$report = new ReportGenerator([], $view);

而不是让ReportGenerator处理任何与之相关的视图,它必须永远不要做,只需传入已创建的视图即可。

视图本身应该在ReportGenerator之外创建(或者任何其他类 - ViewFactory除外)。

在ViewFactory中,您始终可以添加其他方法来处理创建新视图的逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.