数据映射器模式和重复对象

我正在开发一个PHP应用程序中使用数据映射器模式,并有一个问题。 目前,您请求具有特定ID的Site对象,映射器将查找该行,创建一个对象并将其返回。 但是,如果您再次为同一个网站执行此操作,则最终会生成两个具有相同数据的不同对象。 例如。:

$mapper = new Site_Mapper();
$a = $mapper->get(1);
$b = $mapper->get(1);

$a == $b // true
$a === $b // false

所以,我的问题是,我应该:

  • 将实例化的Site对象存储在映射器中,以便我可以在创建新对象之前检查它们是否已经存在(如果存在多个相同类型的映射器,则可能会出现问题)
  • 与#1一样,但确保每个映射器只有一个实例
  • 与#1一样,但使用静态属性,因此多个实例不成问题
  • 不要担心,因为这可能不是问题

  • 我会以某种方式进行缓存 - 静态映射器类将是我的第一选择,这是我所见过的最多的。 否则,你的选项2(这是单例模式)可能是最好的选择。

    请记住,在进行更新时需要清除此缓存以避免返回陈旧的数据。

    话虽如此,除非你正在做一些事情以获得大量的使用,或者做了很多的查询,它可能并不重要。 (你的4)

    另外值得一看的是指导(我确定有很多例子,我只知道这个最好),Propel(http://propel.phpdb.org/)有缓存功能 - 可能值得看看它是如何做的它? 或者只是用它可能?


    你正在寻找的是身份地图模式。 不过,要小心所谓的“阅读不一致”。 当您使用“旧实例”时,数据库可能已经被更改。 当你编辑你的对象时,另一个用户可能会得到它的一个实例,更快地改变它并且更快地保存它。 然后另一个对象再次覆盖所有这些更改。 在网络上,尽管可能不是一个很大的问题,因为“页面”很快就会通过,没有任何对象能够存活超过几分钟。


    我知道很久以前问过这个问题,如果其他人遇到类似的困境,仍然想回答。 其实作者所做的上述#1,2,3建议都是相关的,为了解决这个问题我们应该全部考虑。

    1)将每个从DB对象中检索到的每个对象存储在映射器中,以便在请求具有相同ID的对象时不必再次执行它。 在所有后续调用中,映射器应该返回存储的对象。 这称为IdentityMap模式。 为了达到这个目的,在映射器中创建一个私有属性来为给定的对象类型保存一个IdentityMap的实例。 如果对象没有被检索到,Site_Mapper-> get()方法应该总是检查给定ID的IdentityMap映射器将去到数据库,但是如果它已经存储在映射中,它将返回缓存的实例,数据库。 那么$ a === $ b应该是true,因为它们是对同一个对象实例的引用。

    2)理想情况下,为了在给定的时间维护一个IdentityMap的单个实例,应始终存在给定数据映射器(Site_Mapper)的一个实例。 这可以使用Singleton模式完成。 这可以使用一些像Site_Mapper :: getInstance()这样的getter方法,它总是会返回给定映射器的同一个实例。 您还必须将__construct()声明为私有方法,以防止使用new产生不必要的实例化,并确保getInstance()是实例化映射器的唯一方法。

    3)作者以上提到的静态属性也是如此。 要在PHP中实现一个Singleton ,必须使用静态属性来保存Mapper的实例。

    我强烈推荐Martin Fowler的书“企业应用程序架构模式”,其中讨论了上述模式等等。 这是一个很好的阅读,尤其是如果您正在使用自己的自定义ORM解决方案。 希望有所帮助。

    链接地址: http://www.djcxy.com/p/56247.html

    上一篇: Data Mapper pattern and duplicate objects

    下一篇: Keeping DAO and domain object separate