我正在用PHP编写自己的MVC框架,仅用于学习目的。有一个路由器/调度程序类来调用正确的控制器/动作等并不是很难。
但现在我正处于我将要使用模型的部分。或者实际上是模型层。但有些东西让我困惑。
很多其他MVC框架都有一个'BaseModel'。我已经读到这实际上是不好的做法,因为“模型”不应该被视为另一个类。但作为一个真正的“层”,可以包含“映射器”模式或“存储库”模式等内容。
但说实话,我认为没有任何优势。对我来说,'BaseModel'类似乎是最快的方法,结果相同。
我可以简单地做一些事情:
class User extends BaseModel
{
// the GetUserBy* could easily be something that's handled by the
// BaseModel class, like in the Repo pattern.
public function getUserByName ( $name )
{
// no error handling of any kind, just for simplicity
return $this->db->exec("SELECT * FROM users WHERE name='".$name."'");
}
// $data = array
public function saveUser ( $data )
{
// Make sure no extra fields are added to the array
$user = array ( 'name' => $data['name'],
'address' => $data['address']);
$this->db->autoSave ( $user );
}
}
但是,如果我要使用存储库模式,那么我必须创建以下内容: 库 实体 DAO
实体有聚合到其他存储库。所以基本上我是手动将我的整个数据库方案写出来对象......
最后,有什么区别?除非我可以通过简单地使用BaseModel类来节省大量时间......
但为什么它仍然被认为是一件坏事?并不是repo模式解耦我的应用程序而不是我现在正在做的事情。因为对我来说,上面提到的那些模式似乎被高估了。它可能只适用于具有共享状态的应用程序;在本地保存对象(在存储库中)并稍后提交它们。
这就是为什么我认为没人能真正回答这个......
但是我仍然希望看到一个让我离开的体面答案:“啊......我在想什么......”。但如果没有,那么我肯定我的情况是BaseModel根本不是坏事,而且大多数博主只是一堆羊: - )
答案 0 :(得分:1)
并不是说repo模式解耦了我的应用程序而不是我 现在做的
您的应用程序与SQL数据库组件紧密耦合(实际上,它们充当您的映射器)。然而,尽管如此,您的设计更像是Repository而不是Active Record方法(这可能是您提到的大多数博主都在关注的)。
活动记录不仅封装了数据,还封装了数据库访问:
$user = new User();
$user->setUsername('jane');
$user->setEmail('jane@foo.bar');
$user->save();
让记录对象不知道持久层(关注点分离)会更好。您的“基础”通过返回用户数据数组来做到这一点,并且当修改这些数组时,必须将它们传递回用户“base”以进行保存。您可以将命名更改为:
class UserRepo extends BaseRepo
{
// user-specific repo code...
}
$userRepo = $this->getRepo('User');
$user = $userRepo->getUserByName('jane');
$user['email'] = 'jane@new.email';
$userRepo->save($user);
拥有基础回购并没有错。
答案 1 :(得分:1)
如果您正在尝试从PHP框架学习良好的MVC实践,那么您做错了。即使PHP中最好的框架也存在设计错误和缺陷。
具有“BaseModel”的框架通常正在实现某种ORM。这里最流行的模式是ActiveRecord。这对于简单的表来说很好,与其他表没有关系(基本上是 - 美化的getter / setter)。但是在处理更复杂的结构和查询时开始崩溃。通常导致广泛的technical debt。
另一个原因,为什么这种方法会导致问题,s在这种情况下你的“模型”也可能有责任。您的业务逻辑与存储紧密相关,存储与逻辑相连。随着应用程序的增长,这种“模型”将累积黑客。
不,“一群博主”不是羊。他们刚刚阅读了有关应用程序架构和面向对象编程的书籍。你上次读这本书的时候是什么时候?
答案 2 :(得分:0)
Model
类应该是抽象的,只定义方法而不实现它们。对于您的User
模型,您可以轻松编写具有所有这些功能的接口GettingUsers
,并在User
模型上实现该接口。
答案 3 :(得分:0)
我根本不会使用基本模型,因为大多数模型都没有他们应该遵循的统一接口。如果您愿意,可以为许多不同类型的模型创建基类(这只是基本的面向对象编程)。
总的来说,我相信模型应该是“松散”组件,您可以与控制器连接并显示一个或多个视图。他们不能真正拥有统一的界面,因为他们都会做不同的事情:有些甚至可能不会与持久性商店交谈,有些可能不会持久,和/或某些可能由其他模型组成。