如何在模型结构上表示强制的业务字段


How to represent mandatory business fields on a model structure?

如果我们使用类型提示,我们可以放置一个强制对象:

public function myMethodThatDoFineStuff(MyObject $myobject) {
}

如果,我们想放置,不是所有对象,而只是它的一些属性,是强制性的,该怎么办?让我们假设我们的领域模型会更好,如果它能更好地表示某个领域。这对我们的商业模式(我们的领域)是否更有意义?我们应该怎么做呢?

应该总是放置ALL对象吗?


澄清建议:

让我们想象一下,为了列出某个作者的书,我们有这样的方法:

public function listBookOfAuthor(Author $author) {
}
现在,让我们假设author对象有大约200个属性,但是,为了处理图书列表,我们只需要它们的名字姓氏

我们应该接收ALL $author对象吗?

我将以以下方式测试所需的属性:

public function listBookOfAuthor(Author $author) {
    if (empty($author->firstName)) {
        throw new listBookOfAuthorException('firstName must be defined');
    }
}

如果你发现你经常这样做,你可以写一些父类,包括一个方法来检查属性是否存在

如果我们想把不是所有对象而是它的一些属性设置为强制,该怎么办?

从技术上讲,您可以创建一个只具有函数期望的某些属性的接口。单独来看,这可能看起来有点像开销,但是接口是值得玩一下的,更多的是在手册中它们是如何在PHP中工作的。

仅仅因为它对我们的商业模式更有意义吗?

我对你们的商业模式一无所知,所以我不能说它是否合理。但是我以为你问的是编程问题而不是业务问题。

我们应该始终放置ALL对象吗?

那么你将失去类型提示,但你将能够传递任何对象。这取决于你想要写的代码有多严格。如果您使用接口,那么在重构代码(更改具体对象实现)以及使用stclass对象时就会非常灵活。然而,对于stdclass对象,函数需要在处理函数的输入之前先验证它得到的是什么。

根据您的模式,方法listBooksOfAuthor()(看起来像服务对象上的方法,如BookService)可能只满足于$authorId,而不是完整的Author对象。

但我想我明白问题的关键。也许Author对象完全填充的代价很高——比如说,从AuthorService::getAuthorById()这样的方法中填充。

对于那些您只需要Author功能的适度子集的情况,那么也许您可以创建一个独特的接口——也许是像AuthorSummaryInterface这样的东西——它只反映您在这些情况下需要的那些方法。允许Author对象实现该接口,这样当您已经拥有Author对象时,您就可以执行只需要有限的Author功能的操作。或者,您可以创建一个方法Author:getSummary(),它返回AuthorSummaryInterface的具体实现。在这个方法中,您可以强制执行您的成员需求——例如,必须有一个名称——并在这些需求未被满足时抛出异常。

您还可以创建一组方法(可能是在AuthorService对象或AuthorSummaryService对象上)来生成AuthorSummary对象。然后,在那些只需要AuthorSummaryInterface功能的情况下,您可以创建这些功能有限、创建成本较低的对象。

只是一些想法。