Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:使用一个类生成另一个类的对象_Java_Oop_Constructor_Factory_Software Design - Fatal编程技术网

Java:使用一个类生成另一个类的对象

Java:使用一个类生成另一个类的对象,java,oop,constructor,factory,software-design,Java,Oop,Constructor,Factory,Software Design,我有两节课SpeciesReader获取文件并解析它们物种存储已从文件中解析的有关物种的特定数据 目前,我有一个方法:SpeciesReader.generateSpecies(),它使用实例化它的文件来创建一个Species对象。这种做法/设计不好吗?我是否应该找到一种方法将其移动到Species中以文件名作为参数的构造函数中?一点也不。这是一种叫做工厂的常见模式 也就是说,工厂通常是在类本身(在本例中是物种)上实现的,而不是在一个单独的类上实现的,但是我认为这样分离它没有问题 至于这一责任是

我有两节课
SpeciesReader
获取文件并解析它们<代码>物种存储已从文件中解析的有关物种的特定数据


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

一点也不。这是一种叫做工厂的常见模式

也就是说,工厂通常是在类本身(在本例中是物种)上实现的,而不是在一个单独的类上实现的,但是我认为这样分离它没有问题

至于这一责任是否应该由物种承担,这取决于档案的性质。如果一个文件只包含一个物种,并且加载该文件没有太大的开销,那么将其作为物种的一部分可能是有意义的


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

您可以使用以下几种模式:

实现哪种模式的选择取决于用例,但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”)

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

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


上面您询问了关于在工厂中使用vs静态方法的问题。我对此的看法是:静态方法对于可读的CTOR是好的,而单例方法很好地激怒了任何喜欢静态方法的人

最好将文件解析与从该文件解析的对象实现分离开来。这被称为“关注点分离”。物种的实现不应该知道或关心它在持久性存储中是如何表示的(在OO设计行话中,它应该是“持久性不可知的”),或者传递给它的构造函数的参数来自哪里。它应该只关心创建后如何与系统中的其他对象交互,不管创建是如何进行的。关于物种如何在持久性存储中表示的问题应该在别处实现,以SpeciesReader为例。

最好将对象与其持久性方式分开。想象一下,如果有很多方法来加载物种——从二进制文件、xml文件、数据库记录、网络套接字等——可怜的物种不想知道你程序的每一部分。

+1对于工厂——可能值得添加一个链接,以进一步阅读有关工厂的资料pattern@Rosarch,添加了factory标记-正如cletus所说,这就是您所拥有的?(使其成为静态)作为一般规则,我尽量避免使用静态方法。在上面的示例中,JVM只有一个SpeciesFactory实例,而singleton实例保证只有一个工厂会被实例化。不管对象引用如何,如果要在物种访问器中缓存某些物种,该怎么办?您不希望对具有静态方法或公共构造函数的Util类执行此操作。