2

我有两节课。SpeciesReader获取文件并解析它们。Species存储有关物种的某些数据,这些数据已从文件中解析。

目前,我有一个方法:SpeciesReader.generateSpecies(),它使用实例化它的文件来创建一个Species对象。这是不好的做法/设计吗?我是否应该找到一种方法将其移至以Species文件名作为参数的构造函数?

4

5 回答 5

8

一点也不。这是一种称为工厂的常见模式。

话虽如此,工厂通常是在类本身(在这种情况下为 Species)而不是单独的类上实现的,但我认为这样分离它没有问题。

至于这个责任是否应该由物种代替,这取决于文件的性质。如果一个文件只包含一个 Species 并且在加载该文件时没有很大的开销,那么让它成为 Species 的一部分可能是有意义的。

但是如果文件包含很多物种或者初始化成本很高,那么将这个职责转移到另一个类并让它负责创建 Species 对象是非常有意义的。

于 2009-09-29T01:45:47.893 回答
0

你所拥有的是工厂方法模式的一个例子。这种创建模式在某些情况下可以很好地使用。然而,我个人的偏好是尝试将其使用限制为仅用于更易读的 ctor 替代品,而不是在其中做任何过于复杂的事情。这是为了简化依赖这个工厂的任何类的测试。

对于具有复杂结构的东西,我会使用Abstract Factory。通过这种方式,我可以测试依赖于所述工厂的组件,而无需创建一堆文件和工厂拥有的任何其他依赖项。

上面你问的是在工厂中有一个单例与一个静态方法。我对此的看法是:静态方法适用于可读的ctors,单例方法会激怒任何喜欢单元测试的人。

于 2009-09-29T09:18:46.373 回答
0

您可以使用几种模式:

选择实现哪种模式取决于用例,但 Cletus 是正确的,工厂似乎是一个不错的选择。

public class SpeciesFactory
{
    private final static SpeciesFactory INSTANCE = new SpeciesFactory();

    private SpeciesFactory() { }

    public static SpeciesFactory getFactory() 
    {
        return INSTANCE;
    }


    public Species getSpecies(String filename)
    {
        Species species = null;
        //do business logic
        return species;
    }

}

您可以通过调用 Species carnivore = SpeciesFactory.getFactory().getSpecies("carnivore.txt"); 来使用它。

于 2009-09-29T02:21:01.593 回答
0

将文件的解析与从该文件解析的对象的实现分开是一个好主意。这被称为“关注点分离”。Species 的实现不应该知道或关心它在持久存储中是如何表示的(在 OO 设计术语中,它应该是“持久不可知论”)或传递给其构造函数的参数来自哪里。它应该只关心创建后如何与系统中的其他对象交互,但是创建是发生的。物种如何在持久存储中表示的问题应该在其他地方实现,在您的情况下是在 SpeciesReader 中。

于 2009-09-29T09:34:56.543 回答
0

将对象与其持久化的方式分开通常是更好的主意。想象一下,如果有很多方法可以加载Species - 从二进制文件、从 xml 文件、从数据库记录、从网络套接字等 - 可怜的 Species 不想知道程序的每个部分。

于 2009-10-01T00:57:48.680 回答