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