为什么我要创建从数据库中检索行的所有搜索/获取函数、实例方法?如果我有一个getByID(id)
或一个findPeople(person attributes)
函数,它要么返回对象,要么抛出异常,那么每次我想调用这些方法之一时创建此类实例的开销有什么理由?
我听说它使事情更容易测试,但在这种情况下,我不明白为什么——实例方法根本不与类的其他属性交互。
为什么我要创建从数据库中检索行的所有搜索/获取函数、实例方法?如果我有一个getByID(id)
或一个findPeople(person attributes)
函数,它要么返回对象,要么抛出异常,那么每次我想调用这些方法之一时创建此类实例的开销有什么理由?
我听说它使事情更容易测试,但在这种情况下,我不明白为什么——实例方法根本不与类的其他属性交互。
通常从 OO 设计的角度来看,静态方法被认为是不好的,因为你失去了所有多态性的好处等。另一个原因可能是重用已经检索到的信息,例如,一旦你选择了一组对象,然后你想要一个子集,您不需要进入数据库,或者您可以创建更具体的选择(您不必手动复制第一个查询,这可能很复杂)。您还可以将实例用作期货或构建器,因此您可以根据需要评估您的查询并同时将其携带到一个实例中。
好吧,问题是,你希望它如何工作......围绕这个概念构建了一些模式。
如果你想得到一个:
如果你有很多相似的东西(比如人的类型),那么你可能想要一个 Abstract Factory。在这种情况下,您可能不希望它是静态的。但是话又说回来,您需要一个实例,以便您可以将各个工厂绑定到抽象工厂。这样,您将绕过“Person Builder”工厂。然后,当您查找个人时,您会调用builder.buildPerson(id)
. 该方法将查找个人,并确定要实际实例化的类,并调用相应的工厂。
如果只有一种“人”,那么我会使用工厂方法。在这种情况下,由于类(及其子类)负责实例化,因此静态方法是首选方式。所以你会打电话给person::getPerson(id)
.
如果你想得到很多:
如果您想获得很多人(例如使用findPeople
方法),那么最终的解决方案可能取决于您的需求。
如果您在创建对象时需要某种效率,那么您可能正在寻找享元模式。
否则,如果您使用的是抽象工厂,则创建一个实例方法来根据属性查找多个。如果您使用的是工厂方法,则添加另一个静态方法来查找它们。
但另一种看待它的方式
是不是对象数据的“存储”和“加载”与对象本身无关,因此它不属于方法(静态或非静态)。在这种情况下,最好有一个代表数据存储的模型。然后,要获取用户列表,您可以调用peoplemodel.getPerson(id)
. 它将针对 DB 获取,并加载构造对象所需的peoplemodel
信息。然后,它会调用 person 类的工厂来构造实际的对象,并返回它。
这很好,因为它将存储与实现分开。当然,它是另一层,但是额外的层可以让你做一些事情,比如拥有多个数据存储,或者为具有不同存储要求的多个应用程序使用同一个 person 类(因为所有类都关心传入的数据)。
所以,总而言之:
现在,您无法通过静态方法实现单独组件的松散耦合,因此在这种情况下,您需要在双方都使用实例。因此,您需要将构建器传递给模型(依赖注入)以创建人员对象。而且由于模型本身是松耦合的,因此您将获得一个实例并将其传递到您需要加载人员的地方。
所以简而言之,这取决于你想要做什么。但是,如果您想要最松散的耦合代码(最可重用和最可维护),那么请远离静态方法并坚持使用抽象工厂/构建器和 DI ...