【问题标题】:PHP OOP: Avoid Singleton/Static Methods in Domain Model PatternPHP OOP:避免领域模型模式中的单例/静态方法
【发布时间】:2010-04-23 09:34:01
【问题描述】:

我了解依赖注入的重要性及其在单元测试中的作用,这就是为什么下面的问题让我停下来的原因:

我努力不使用单例的一个领域是身份映射/工作单元模式(它密切关注域对象状态)。

//Not actual code, but it should demonstrate the point    

class Monitor{//singleton construction omitted for brevity
    static $members = array();//keeps record of all objects
    static $dirty = array();//keeps record of all modified objects
    static $clean = array();//keeps record of all clean objects
}

class Mapper{//queries database, maps values to object fields
    public function find($id){
        if(isset(Monitor::members[$id]){
        return Monitor::members[$id];
    }
    $values = $this->selectStmt($id);
    //field mapping process omitted for brevity
    $Object = new Object($values);
    Monitor::new[$id]=$Object
    return $Object;
}

$User = $UserMapper->find(1);//domain object is registered in Id Map
$User->changePropertyX();//object is marked "dirty" in UoW

// at this point, I can save by passing the Domain Object back to the Mapper
$UserMapper->save($User);//object is marked clean in UoW

//but a nicer API would be something like this
$User->save();

//but if I want to do this - it has to make a call to the mapper/db somehow    
$User->getBlogPosts();

//or else have to generate specific collection/object graphing methods in the mapper
$UserPosts = $UserMapper->getBlogPosts();
$User->setPosts($UserPosts);

关于如何处理这种情况的任何建议?

我不愿意将映射器/数据库访问的实例传递/生成到域对象本身以满足 DI - 同时,避免导致域对象内大量调用外部静态方法。

虽然我想如果我希望“保存”成为其行为的一部分,那么在其构造中需要一个这样做的工具。也许是责任的问题,域对象不应该有保存的负担。这只是 Active Record 模式中的一个非常简洁的功能 - 以某种方式实现它会很好。

【问题讨论】:

    标签: php oop model singleton dns


    【解决方案1】:

    我所做的,尽管可能不是最好的做法,是为我的类制定一个明确的命名约定,FI:user_User 是域对象,user_mapper_User 是映射器。

    在我的父级 domainObject 中,我编写了逻辑来找到它的映射器。

    然后你有几个选项可以委托给它,一个明显的方法是使用domainObject 中的__call() 方法。

    【讨论】:

    • 当然,我也是这样做的。问题是:您是创建映射器的新实例,还是对存在于用户之外的映射器进行静态调用(假设用户映射器必须已经存在才能有用户)?因为如果你调用一个新的映射器,你可能需要调用一个新的数据库句柄,加上对工作单元和 ID 映射的引用...... - 而外部类已经完成了所有这些设置
    • 我将 DB 句柄(在我的例子中为 MDB2)静态存储在父映射器类中,所以无论我有多少个映射器实例,它们都共享同一个句柄。
    • 啊,我明白了,这不是 Monostate 类模式吗?
    • 我不知道这是一种模式。但显然是的,它是。谢谢你让我知道:)
    猜你喜欢
    • 2012-09-25
    • 1970-01-01
    • 2011-12-19
    • 2011-02-20
    • 2014-01-17
    • 2013-01-19
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    相关资源
    最近更新 更多