我正在使用服务层,直到现在我使用的是ServiceObject(它实现了ArrayAccess,Iterator,Countable),但我想知道这是否是一个好主意。
你会做:
ArticleService::createArticle($articleData, $userId);
或
ArticleService::createArticle(ServiceObject $data);
$data
在哪里:
array(
'title' => 'Lorem ipsum',
'body' => 'Dolor sid amet',
'userId' => 55,
);
ServiceObject 的优点是为每个方法提供通用签名,但有时它看起来效率不高,而且没有被广泛使用,它会失去兴趣。
任何反馈?
将其更改为:
ArticleService::createArticle($title, $body, $user_id);
这非常清楚创建"文章"需要什么。
像您的$articleData
和$data
这样的"选项"数组不可能明智地智能感知,我建议不要这样做。
你的想法扔给一个通用的ServiceObject
这实际上是一个非常糟糕的主意。你的动机是高尚的,但这是错误的解决方案。
如果您需要更多说服力,请随时戳。
我认为这里最好的方法是拥有类似的东西
$article = new Article;
$article->title = "Lorem ipsum"
$article->body = "Dolor sit amet"
$article->creator = $userID
ArticleService::createArticle($article)
尽管"createArticle"可能不再是该函数的最佳名称,因为 Article 对象已经创建。你可能会有类似ArticleService::publishArticle($article)
的东西,虽然我不知道你在做什么。
你想要的是将数据的构造(Article
)与它的使用(ArticleService
)分开。
我真正想说的是,不要使createArticle的参数成为泛型数组或"ServiceObject",两者都是参数列表的无用抽象,使其成为真正表示相关实体的类。
我投票支持该对象,因为复杂系统中的代码完成是非常好的事情,并且还有一些自动验证,因为当您知道对象类型时,您可以以某种方式验证它。但是如果你在createSomething中没有复杂的逻辑,那么数组也可以。
第二个更好,你永远不会遇到人们以错误的方式称呼你的方法的问题!阅读和查看所需内容也更容易。对于我作为开发人员来说,很明显我必须传递一个类型 ServiceObject
的对象,然后我开始搜索此类的文档或示例或接口。但是在第一个示例中,我必须阅读 createArticle
的代码才能弄清楚如何处理这两个参数。
第二种方法还将帮助您随着时间的推移保持 API/签名干净。当内部需要一些额外的数据时createArticle
您只需通过ServiceObject
传递它们,而无需更改签名!
第一个示例的更好签名是:
ArticleService::createArticle(array $articleData, $userId);
在这种情况下$articleData
必须是一个数组。这可以防止错误。在 PHP 函数参数中,只能使用数组和类名进行强制转换。
没有正确的方法,但我会在这种特定情况下使用ArticleService::createArticle($articleData, $userId);
。
我假设文章有一个必需的非空属性 userId(您从上下文中获得)和一个可选(不是很重要)的内容数据,这些数据可能是空的。
这样,文章和用户对象之间的联系就很明显了。可读性略有提高。否则,您需要完全熟悉所需的数据和createArticle方法。
作为证明:当我看到ArticleService::createArticle($articleData, $userId)
时,我立即明白了该方法在做什么以及对输入数据的期望,而第二个让我感到困惑。
此外,如果缺少userId,此时将收到错误,而不是在将其插入数据库的那一刻,您可能会遇到更难跟踪的SQL错误。
另一方面,在 ZF 中,使用数组作为参数是很常见的,因此您的代码可能看起来不同。
但是,这主要取决于您的喜好。
我认为更好的方法是注入一个对象。但是为什么服务对象在那里呢?你有一个方法createArticle,那么将文章对象传递给它是合乎逻辑的,不是吗?这样,组织验证过程会更简单,您只需标记要在注释中进行验证的字段。
这也是您使用的方法问题。如果在服务层中使用数据映射器模式,则显然应该向其传递对象。
对于对象,您可以在对象之间拥有透明和清晰的通信接口。对于数组,不清楚您传输什么类型的数据,什么样的字段等等。