Java:使用一个类生成另一个类的对象
我有两节课。 SpeciesReader
获取文件并解析它们。 Species
存储有关某个物种的某些数据,这些数据已从文件中解析出来。
目前,我有一个方法:SpeciesReader.generateSpecies()
,它使用实例化它的文件来创建 Species
对象。这是不好的做法/设计吗?我是否应该找到一种方法将其移至以文件名作为参数的 Species
构造函数?
I have two classes. SpeciesReader
takes files and parses them. Species
stores certain data about a species, which has been parsed from the file.
Currently, I have a method: SpeciesReader.generateSpecies()
, which uses the file with which it was instantiated to create a Species
object. Is this bad practice/design? Should I somehow find a way to move this to a constructor in Species
that takes the filename as an argument?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一点也不。这是一种称为工厂的常见模式。
话虽这么说,工厂通常是在类本身(在本例中为 Species)上实现,而不是在单独的类上实现,但我认为这样分离它没有问题。
至于这个责任是否应该由物种承担,这取决于文件的性质。如果一个文件仅包含一个物种,并且加载该文件没有太大的开销,那么将其作为物种的一部分可能是有意义的。
但是,如果文件包含大量物种或者初始化成本很高,那么将该责任转移到另一个类并让它负责创建物种对象是非常有意义的。
Not at all. That's a common pattern called a factory.
That being said, factories are usually implemented on the class itself (Species in this case) rather than a separate class but I see no problem with separating it like that.
As for whether this responsibility should go on Species instead, that depends on the nature of the files. If a file contains merely one Species and there's no large overhead in loading that file then it might make sense to make it part of Species.
But if the file contains lots of species or is expensive to initialize then it makes perfect sense to move that responsibility to another class and have it be responsible for creating Species objects.
您可以使用以下几种模式:
选择实现哪种模式取决于用例,但 Cletus 是正确的,工厂似乎是一个不错的选择。
您可以通过调用 Species carnivore = SpeciesFactory.getFactory().getSpecies("carnivore.txt"); 来使用它
There are a few patterns you could use:
The choice of which pattern to implement would depend on use case, but Cletus is correct, factory seems like a good choice.
You would use it by calling Species carnivore = SpeciesFactory.getFactory().getSpecies("carnivore.txt");
您拥有的是工厂方法模式的示例。这种创建模式在某些情况下可以很好地使用。然而,我个人的偏好是尝试将其用法限制为仅作为更易读的 actor 替代品,而不是在其中执行任何过于复杂的操作。这是为了简化依赖于该工厂的任何类的测试。
对于结构复杂的东西,我会使用抽象工厂。这样我就可以测试依赖于所述工厂的组件,而无需创建一堆文件和工厂具有的任何其他依赖项。
上面您询问了 Singleton 与工厂中的静态方法。我对此的看法是:静态方法有利于可读的构造函数,单例方法会激怒任何偏好 单元测试。
What you have is an example of the Factory Method Pattern. This creational pattern can be used well in some cases. My personal preference however is to try and restrict it usage to only that of a more readable replacement for a ctor and not do anything overly complex within it. This is to simplify testing of any classes that depend on this factory.
For something with a complex construction I would use Abstract Factory. This way I can test components with a dependency on said factory without creating a bunch of files and any other dependencies the factory has.
Above you ask about having a Singleton vs a static method in factory. My take on this is: A static method is good for readable ctors, a singleton is good irritating anyone with a preference for unit testing.
将文件的解析与从该文件解析的对象的实现分开是一个好主意。这称为“关注点分离”。 Species 的实现不应该知道或关心它如何在持久性存储中表示(用 OO 设计术语来说,它应该是“持久性不可知的”)或者传递给其构造函数的参数来自何处。它应该只关心创建后如何与系统中的其他对象交互,无论创建是如何发生的。对物种如何在持久存储中表示的关注应该在其他地方实现,在您的例子中是在 SpeciesReader 中。
It's a good idea to separate the parsing of a file from the implementation of objects parsed from that file. This is known as "Separation of Concerns". The implementation of Species should not know or care how it is represented in persistent storage (in OO design jargon, it should be "persistence agnostic") or where the parameters passed to its constructor come from. It should only care about how interacts with other objects in the system once it has been created, however that creation occurs. The concern of how Species are represented in persistent storage should be implemented elsewhere, in your case in the SpeciesReader.
将对象与其持久化方式分开通常是更好的主意。想象一下,如果有多种方法加载Species——从二进制文件、从xml文件、从数据库记录、从网络套接字等等——可怜的Species不想知道程序的每个部分。
It is often better idea to separate object from the way it is persisted. Imagine if there are many ways to load Species - from binary file, from xml file, from database record, from network socket, etc - poor Species does not want to know about every part of your program.