【问题标题】:Search OOP - Model design (MVC) [closed]搜索 OOP - 模型设计(MVC)[关闭]
【发布时间】:2011-12-07 16:12:23
【问题描述】:

我想在模型(MVC/框架)中创建一个“搜索”类,我想知道该方法应该如何构造。

有两种类型的搜索和SQL查询包含一些JOIN。

这将允许客户从一个搜索文本框中输入邮政编码、公司名称或城市:

SELECT * FROM Shop as S
   JOIN shop_options as O on O.ShopID = S.ShopID
   JOIN shop_openhours as OH on OH.ShopID = S.ShopID
WHERE (O.postcode = :postcode  OR S.company LIKE :companyName OR S.city = :townName)

如果客户通过 url 访问特定城镇,例如:/town/London

那么查询将如下所示:

SELECT * FROM Shop as S
   JOIN shop_options as O on O.ShopID = S.ShopID
   JOIN shop_openhours as OH on OH.ShopID = S.ShopID
WHERE S.city = :townName

需要在模型中对数据进行操作,以确定商店是开门还是关门。

这是我想出的快速设计:

class modelSearch extends Model {

    public $id;
    public $shopName;
    public $isOpen = false;

    public static function findAll($searchType) {
        $SQL = "SELECT * FROM Shop as S
                 JOIN shop_options as O on O.ShopID = S.ShopID
                 JOIN shop_openhours as OH on OH.ShopID = S.ShopID
               WHERE (O.postcode = :postcode  OR S.company LIKE :companyName OR S.town = :townName)";

         //fetch data into $data

        $search = array();
        foreach ($Dbdata as $data) {
            $searchModel = new modelSearch();
            $searchModel->isOpen = modelSearch::isShopOpen($data['opentime'], $data['closetime']);
            $searchModel->id = $data['id'];
            $searchModel->shopName = $data['shopName'];

            $search[] = $searchModel;
        }
        return $search;
    }

    public static function findByTown($search) {
        //Same code as findAll() apart from SQL query (WHERE)
        //WHERE S.town = :townName
    }

    public static function isShopOpen($open, $close) {
        $min = ($open > 123) ? $open : 345; // Earliest allow time
        if ($close < $min)
        //some block code here
            return true;
        return false;
    }
}

我走在正确的道路上还是可以改进什么?

【问题讨论】:

  • 有效吗?你在寻找什么答案?

标签: php model-view-controller oop class model


【解决方案1】:

抱歉,这还不是正确的方法。静态函数是包装在类中的过程代码。去掉所有的静态,它会看起来更像 OOP,尽管 OOP 真正是关于你创建的对象的交互。一个接一个地调用一个方法来实现你想要的,只是写函数的一种奇特方式。

这是我要做的:

class modelSearch extends Model {

   /**** public variables should not be common in OOP.  We want to control
    **** the interface.  Someone could change these if they were left public.
    ****/
   private $id;
   private $shopName;
   private $isOpen = false;

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

    public function findAll($searchType) {
        $SQL = "SELECT * FROM Shop as S
                 JOIN shop_options as O on O.ShopID = S.ShopID
                 JOIN shop_openhours as OH on OH.ShopID = S.ShopID
               WHERE (O.postcode = :postcode  OR S.company LIKE :companyName OR S.town = :townName)";


        /**** There is no need to instantiate any more objects in the class to
     **** do the work. I am replacing the rest of your function with
     **** pseudo-code.
     ****/
    $data = execution_of_sql();

    // I am not clear on what you want.
        foreach ($data as $record) {
       if ($this->isShopOpen($record['opentime'], $record['closetime']))
       {
          $openShops[] = array('id' => $record['id'],
                   'name' => $record['shopName']);
       }
    }

    return $openShops;

    // **** Notice how there is no need to instantiate another object
    // **** because we are the object.
    // $searchModel = new modelSearch();

    }

    // **** These could possibly be joined into 1 function with more parameters.
    public function findByTown($search) {
        //Same code as findAll() apart from SQL query (WHERE)
        //WHERE S.town = :townName
    }


    // **** protected and private hide information so that you can ignore it
    // **** outside the class.  The interface to the class is now less
    // **** cluttered.
    protected function isShopOpen($open, $close) {
        $min = ($open > 123) ? $open : 345; // Earliest allow time
        if ($close < $min)
        //some block code here
            return true;
        return false;
    }
}

【讨论】:

  • 这是一个好的开始。更好的办法是将数据库调用包装在实现接口的存储库中。这样,模型不知道实际如何进行搜索,并且存储库可以与任何后备数据库一起使用。模型所要做的就是委托给 repo 的搜索方法。在 PHP 中,包装 PDO 对象的存储库可能是理想的选择。
  • 同意,但很难以一种不可怕的方式写出来。
  • @kevinmajor1 你指的是像 db 类吗?我已经实现了这个并使用 PDO :)
  • 是的。您的模型不应该直接执行甚至创建 SQL。他们应该做的是包含对为模型执行所有脏工作的存储库的引用(读取:私有数据成员)。以你的 findAll() 方法为例:它最多应该只有几行。一个委托给存储库,一个返回结果,以及一些防御性错误处理/预期代码。重点在于分离关注点——你的模型不应该关心从数据库中获取结果集所需的基本 SQL。
【解决方案2】:

是的,你的方法是正确的。遵循一个 MVC 框架。我认为你正在为此遵循一个框架。你创建了一个类 Search as Model 并且还具有控制器和视图。

【讨论】:

    猜你喜欢
    • 2015-07-11
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2012-03-16
    • 2013-05-03
    • 1970-01-01
    相关资源
    最近更新 更多