为什么我想让所有从数据库检索行的搜索/获取函数,实例方法?如果我有一个getByID(id)
或findPeople(person attributes)
函数,它要么返回对象,要么抛出一个异常,每当我想调用其中一种方法时,创建这个类的实例的开销是多少?应该搜索/获取从数据库中检索行的方法是实例方法还是静态方法?
我听说它使事情更具可测性,但在这种情况下,我不明白为什么 - 实例方法根本不与类的其他属性进行真正的交互。
为什么我想让所有从数据库检索行的搜索/获取函数,实例方法?如果我有一个getByID(id)
或findPeople(person attributes)
函数,它要么返回对象,要么抛出一个异常,每当我想调用其中一种方法时,创建这个类的实例的开销是多少?应该搜索/获取从数据库中检索行的方法是实例方法还是静态方法?
我听说它使事情更具可测性,但在这种情况下,我不明白为什么 - 实例方法根本不与类的其他属性进行真正的交互。
那么,问题是,你想如何工作......围绕这个概念构建了一些模式。
如果你想获得一个:
如果你有很多类似的东西(如类型的人),那么你可能要一个Abstract Factory。在这种情况下,你可能不希望它是静态的。但是再一次,你需要一个实例,以便你可以将你的单个工厂绑定到抽象工厂。这样,你会传递一个“人员建造者”工厂。然后,当你查找一个人时,你可以拨打builder.buildPerson(id)
。该方法将查找个人,并确定实际实例化的类,并调用相应的工厂。
如果只有一种“人”,那么我会使用Factory method。在那种情况下,由于类(及其子类)负责实例化,因此静态方法是首选方法。所以你会打电话person::getPerson(id)
。
如果你想获得许多:
如果你想获得许多人(如用findPeople
方法),那么最终的解决方案可能取决于你的需要。
如果您在创建对象时需要某种效率,那么您可能会寻找Flyweight模式。
否则,如果您使用的是抽象工厂,那么请创建一个实例方法以根据属性查找多个。如果您使用的是工厂方法,请添加其他静态方法来查找它们。
但看它
另一种方式是,“存储”和对象数据的“加载”是没有关系的对象本身,所以它不属于作为方法(静态或不)。在这种情况下,最好有一个代表数据存储的模型。然后,要获得用户列表,请拨打peoplemodel.getPerson(id)
。 peoplemodel
将对数据库进行读取,并加载构建对象所需的信息。然后,它会调用person类中的工厂来构造实际的对象,并将其返回。
这很好,因为它将存储与实施分开。当然,这是另一层,但是额外的层可以让你做像有多个数据存储的事物,或者为具有不同存储需求的多个应用程序使用相同的人员类(因为所有类都关心的是传入的数据)。
所以,结论:
现在,你无法通过静态的方法,可以实现独立的组件的松散耦合,所以在这种情况下,你需要在两侧使用实例。因此,您需要将构建器传递给模型(依赖注入)以创建人员对象。而且由于模型本身是松散耦合的,你会得到一个实例并将其传递到需要加载人员的地方。
总之,这取决于你想要做什么。但是,如果你想要最松散的耦合代码(最可重用和最可维护),那么远离静态方法并坚持抽象工厂/建设者和DI ...
一般从OO设计的角度来看,静态方法被认为是不好,因为你失去了所有的多态性好处等。另一个原因可能是重用已经检索的信息,例如一旦你选择了一组对象,然后你想要一个子集,你就不需要进入数据库,或者你可以创建更具体的选择(你不必手动复制第一个查询,这可能很复杂)。您还可以使用实例作为期货或建设者,这样您就可以根据需要评估您的查询,并在此期间在实例中进行查询。
我是静态方法方法的粉丝,虽然有时候可以用另一种方式来做(Perons的一个实例可能有一个方法MySiblings,它会返回与第一个实例相关的Person实例集合) 。对于一般数据访问来说似乎更清洁。但是,我很乐于听到以其他方式进行操作的原因(实例方法)。我自己的经验法则是,如果一个特定的DA方法可能在整个应用程序中使用,并且不依赖于特定实例的成员,我倾向于将其作为一个DA特定类的静态记忆。 – XIVSolutions 2011-02-01 14:33:35