为什么我要让所有从数据库检索行的搜索/获取函数成为实例方法?如果我有一个 getByID(id)
或 findPeople(person attribute)
函数,要么返回对象,要么抛出异常,那么开销的合理性是什么每次我想调用这些方法之一时创建此类的实例?
我听说它使事情变得更加可测试,但在这种情况下,我不明白为什么——实例方法根本不与类的其他属性交互。
最佳答案
好吧,问题是,您希望它如何工作...围绕这个概念构建了一些模式。
如果您想获得一个:
如果您有很多相似的事物(例如人的类型),那么您可能需要 Abstract Factory 。在这种情况下,您可能不希望它是静态的。但话又说回来,您需要一个实例,以便可以将各个工厂绑定(bind)到抽象工厂。这样,您就可以绕过“人员构建器”工厂。然后,当您查找个人时,您可以调用 builder.buildPerson(id)
。该方法将查找个体,并确定要实际实例化的类,并调用相应的工厂。
如果只有一种类型的“人”,那么我会使用 Factory method 。在这种情况下,由于类(及其子类)负责实例化,因此静态方法是首选方式。因此,您可以调用 person::getPerson(id)
。
如果你想获得很多:
如果您想吸引很多人(例如使用 findPeople
方法),那么最终的解决方案可能取决于您的需求。
如果您需要某种类型的对象创建效率,那么您可能正在寻找 Flyweight模式。
否则,如果您使用抽象工厂,则创建一个实例方法来根据属性查找多个工厂。如果您使用工厂方法,请添加另一个静态方法来查找它们。
但是另一种看待它的方式
对象数据的“存储”和“加载”与对象本身无关,因此它不属于方法(静态或非静态)。在这种情况下,最好有一个代表数据存储的模型。然后,要获取用户列表,您需要调用 peoplemodel.getPerson(id)
。 peoplemodel 将获取数据库,并加载构建对象所需的信息。然后,它将调用 person 类上的工厂来构造实际的对象,并将其返回。
这很好,因为它将存储与实现分开。当然,这是另一层,但是额外的层可以让您执行诸如拥有多个数据存储之类的操作,或者对具有不同存储要求的多个应用程序使用相同的人员类(因为所有类关心的是传入的数据)。
所以,结论:
现在,您无法通过静态方法实现单独组件的松散耦合,因此在这种情况下,您需要在两侧使用实例。因此,您可以将构建器传递给模型(依赖注入(inject))来创建人员对象。由于模型本身是松耦合的,因此您将获得一个实例并将其传递到需要加载人员的地方。
简而言之,这取决于您想要做什么。但是,如果您想要最松散耦合的代码(最可重用和最可维护),那么请远离静态方法并坚持使用抽象工厂/构建器和 DI...
关于oop - 从数据库检索行的 search/get 方法应该是实例方法还是静态方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4862832/