从数据库检索行的 search/get 方法应该是实例方法还是静态方法?
为什么我想要使所有从数据库检索行的搜索/获取函数、实例方法?如果我有一个 getByID(id)
或 findPeople(person attribute)
函数,要么返回对象,要么抛出异常,那么开销的合理性是什么每次我想调用这些方法之一时创建此类的实例?
我听说它使事情变得更加可测试,但在这种情况下,我不明白为什么——实例方法根本不与类的其他属性交互。
Why would I want to make all my search/get functions that retrieve rows from a database, instance methods? If I have a getByID(id)
or a findPeople(person attributes)
function, that either returns object(s) or throws an exception, what justification is there for the overhead of creating an instance of this class every time I want to call one of these methods?
I've heard it makes things more testable, but in this case I don't see why -- the instance methods don't really interact with the other properties of the class at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,问题是,你希望它如何工作......围绕这个概念构建了一些模式。
如果你想要一个:
如果你有很多相似的东西(比如人的类型),那么你可能需要一个 抽象工厂。在这种情况下,您可能不希望它是静态的。但话又说回来,您需要一个实例,以便可以将各个工厂绑定到抽象工厂。这样,您就可以绕过“人员构建器”工厂。然后,当您查找个人时,您可以调用
builder.buildPerson(id)
。该方法将查找个体,并确定要实际实例化的类,并调用相应的工厂。如果只有一种类型的“人”,那么我会使用工厂方法。在这种情况下,由于类(及其子类)负责实例化,因此静态方法是首选方式。因此,您可以调用
person::getPerson(id)
。如果您想获得很多:
如果您想获得很多人(例如使用
findPeople
方法),那么最终的解决方案可能取决于您的需求。如果您需要某种形式的对象创建效率,那么您可能会寻找Flyweight 模式。
否则,如果您使用抽象工厂,则创建一个实例方法来根据属性查找多个工厂。如果您使用工厂方法,请添加另一个静态方法来查找它们。
但另一种看待它的方式
是,对象数据的“存储”和“加载”与对象本身无关,因此它不属于方法(静态或非静态) 。在这种情况下,最好有一个代表数据存储的模型。然后,要获取用户列表,您需要调用
peoplemodel.getPerson(id)
。 peoplemodel 将获取数据库,并加载构建对象所需的信息。然后,它将调用 person 类上的工厂来构造实际的对象,并将其返回。这很好,因为它将存储与实现分开。当然,这是另一层,但是额外的层可以让您执行诸如拥有多个数据存储之类的操作,或者对具有不同存储要求的多个应用程序使用相同的人员类(因为所有类关心的是传入的数据)。
所以,结论:
现在,您无法通过静态方法实现单独组件的松散耦合,因此在这种情况下,您需要在两侧使用实例。因此,您可以将构建器传递给模型(依赖注入)来创建人员对象。由于模型本身是松耦合的,因此您将获得一个实例并将其传递到需要加载人员的地方。
简而言之,这取决于您想要做什么。但是,如果您想要最松散耦合的代码(最可重用和最可维护),那么请远离静态方法并坚持使用抽象工厂/构建器和 DI...
Well, the question is, how do you want it to work... There are a few patterns built around this concept.
If you want to get one:
If you have many similar things (like types of people), then you might want an Abstract Factory. In that case, you'd likely not want it to be static. But then again, you'd want an instance so you can bind your individual factories to the abstract factory. That way, you'd pass around a "Person Builder" factory. Then, when you're looking up an individual, you'd call
builder.buildPerson(id)
. That method would look up the individual, and determine the class to actually instantiate, and call the respective factory.If there's only one type of "person", then I'd use a Factory method. In that case, since the class (and its children) are responsible for instantiation, static methods are the preferred way. So you'd then call
person::getPerson(id)
.If you want to get many:
If you want to get many people (Such as with a
findPeople
method), then the ultimate solution would likely be dependent upon your need.If you need some kind of efficiency with object creation, then you're likely looking for a Flyweight pattern.
Otherwise, if you're using an abstract factory, then make an instance method to find multiple based upon attributes. If you're using a factory method, then add another static method to find them.
But another way of looking at it
Is that "storing" and "loading" of the data for an object is not related to the object itself, so it does not belong as a method (static or not). In that case, it would be better to have a model that represents the datastore. Then, to get a list of users, you'd call
peoplemodel.getPerson(id)
. Thepeoplemodel
would fetch against the DB, and load the information necessary to construct the object(s). Then, it would call the factory on the person class to construct the actual object, and return it.This is nice, because it's separating the storage from the implementation. Sure, it's another layer, but the extra layer lets you do things like have multiple datastores, or use the same person class for multiple applications with different storage requirements (since all the class cares about is the data passed in).
So, in conclusion:
Now, you can't achieve loose coupling of separate components via static methods, so in this case you'd need to use instances on both sides. So you'd pass in a builder to the model (dependency injection) to create the people objects. And since the model itself is loose-coupled, you'd get an instance of that and pass it where you need to load people.
So in short, it depends on what you're trying to do. But if you want the loosest coupled code (most reusable and most maintainable), then stay away from static methods and stick to abstract factories/builders and DI...
一般来说,从面向对象设计的角度来看,静态方法被认为是不好的,因为你失去了所有多态性的好处等。另一个原因可能是重用已经检索到的信息,例如,一旦你选择了一组对象,然后你想要一个子集,您不需要进入数据库,或者您可以创建更具体的选择(您不必手动复制第一个查询,这可能很复杂)。您还可以使用实例作为 future 或构建器,这样您就可以根据需要评估查询并同时将其携带在实例中。
Generally from the OO design standpoint, static methods are considered to be bad, bacause you loose all the polymorphism benefits etc. The other reason might be to reuse already retrieved information, e.g. once you select a set of objects and then you want a subset, you dont need to go into DB, or you can create more specific selects (you don't have to manually duplicate the first query, which might have been complex). You can also use instances as futures or builders, so you can evaluate your query as needed and carry it in an instance in the meantime.