Nick Heiner
Nick Heiner

Reputation: 122480

Java: Using one class to generate objects of another

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?

Upvotes: 2

Views: 2399

Answers (5)

Pavel Feldman
Pavel Feldman

Reputation: 4719

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.

Upvotes: 0

Nat
Nat

Reputation: 9951

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.

Upvotes: 0

Michael Lloyd Lee mlk
Michael Lloyd Lee mlk

Reputation: 14661

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.

Upvotes: 0

Droo
Droo

Reputation: 3205

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.

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;
    }

}

You would use it by calling Species carnivore = SpeciesFactory.getFactory().getSpecies("carnivore.txt");

Upvotes: 0

cletus
cletus

Reputation: 625097

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.

Upvotes: 8

Related Questions