数据库实体对象模型——松散表示与严格表示


Database Entity Object Model -- Loose vs Strict Representation?

我正试图决定这个困境,因为我正在编写一些PHP API。我正在尽我最大的努力编写一些可靠的api,而不是一个PHP老手,通过在黑暗中摸索,希望找到一些最佳实践。我也不确定我是否使用了正确的术语,所以请纠正我。

我有一些实体将它们的数据存储在数据库中,我以面向对象的方式对其建模。我的模型是否总是严格地表示数据库中的当前内容?



松散的数据库表示

  • 用户可以自由更改模型的属性,然后将更改保存到数据库中。
  • 模型并不总是反映数据库中的内容,因为用户可以任意更改模型。

,

<?php
  // Write a snippet
$snippet = (new Snippet)
    ->label("grapes")
    ->content("wine")
    ->save();
  // Load a snippet
$snippet = (new Snippet)
    ->label("bananas")
    ->load();
  // Update an existing snippet
$snippet
    ->content("potassium")
    ->save();
?>




严格的数据库表示

  • 用户不能自由更改模型的属性。只有getter提供给属性(没有setter)。
  • 保证模型总是代表数据库中的内容。
  • 改变模型的唯一方法是同时改变数据库中的内容。

,

<?php
  // Write a snippet
$snippet = (new Snippet)->write("grapes", "wine");
  // Load a snippet
$snippet = (new Snippet)->read("bananas");
  // Update an existing snippet
$snippet->update("potassium");
?>

您希望使用哪种API样式?

我从宽松模型开始,并开始怀疑严格模型是否是更好的做事方式?严格模型的完整性是否超过了松散模型的灵活性?

我愿意接受任何想法、评论、赞成/反对、替代方案和想法;我只是想做正确的PHP,并做出一个好的API,其他程序员发现满意:)

这两个例子都让我想起了ActiveRecord模式。ActiveRecord是当你赋予你的对象CRUD方法——也就是说,他们知道如何从数据源创建、读取、更新和删除自己。

现在,如果我正确地理解你,你想知道是否能够设置模型的属性更好,然后调用CRUD方法,或者直接调用CRUD方法,在内部传递设置属性的参数?在任何一种情况下,似乎两种"表现"都是松散或严格的。至于一个好的API,我想说"松散"的表示将是大多数人所期望的。

现在,来看看建议。有两种流行的与数据源交互的模式。一个是ActiveRecord模式,另一个是Repository模式。我已经简要地描述了ActiveRecord模式。Repository Pattern从模型中剥离出数据交互职责,并将其放入"Repository"类中。这个存储库类负责CRUD操作。有很多关于ActiveRecord和Repository模式的优缺点的帖子,所以你可以去查一下。我要说的是,储存库模式作为"更好"的模式被广泛接受。

指的是当你说,"用户可以自由地更改模型的属性,然后将更改保存到数据库中。"一般来说,对象应该保护它们的不变量。也就是说,您不应该允许将它们的数据设置为无效状态。对象应该用它需要的信息构造,并且不提供setter,除非改变对象中的值是有意义的。即使这样,你也可以给setter起一个比setX()更好的名字。ei: fillUp()而不是setFuel()。

我个人会用存储库模式来设计东西:

class SnippetRepository
  void save(Snippet snippet) { ... }
  void update(Snippet snippet) { ... }
  boolean delete(Snippet snippet) { ... }
  Snippet load(SnippetId id) { ... }
end
$snippet = (new Snippet)
    ->label("grapes")
    ->content("wine");
snippetRepository.save($snippet);