Giannis
Giannis

Reputation: 5516

Creating extensible code

I am making an application where the user is prompt at some point to create a new file (object not file in OS). That file represents one of several subclasses of an abstract class named FilePack. The user will choose the type of the file from a list (in a JOptionPane) then that option is forwarded to a method which will create the appropriate subclass.

An example: User clicks on "create new file" button. JOptionPane comes with a list of available FilePack subclasses. User selects "Type A". Selection forwarded to method which creates the appropriate subclass.

Which would be the optimal way of handling this operation which will allow the code to work when introducing new FilePack subclasses without having to go everywhere and changing bits of code?

(at this point you have to change the list in JOptionPane and the method creating the subclasses, but its possible changes will need to happen on more places later in development)

Also, is it possible to get two inputs from a JOptionPane? One using textfield and one from list ?Im only able to do one at time.

Upvotes: 1

Views: 365

Answers (2)

Tudor
Tudor

Reputation: 62439

IMO, the best solution for this scenario would be to use the factory pattern. This works by having an abstract class FileFactory, with a method producing generic Files. You then create a concrete factoriy, creating implementations of File. Example:

public interface FileFactory {
   public File createFile();
}

public abstract class File {
}

public class File1 extends File {
}

public class File2 extends File {
}

public class ConcreteFileFactory implements FileFactory {
    public File createFile(int fileType) { 
        switch(fileType) {
            case 1: return new File1();
            case 2: return new File2();
            // etc.
        }
    }
}

Adding new Files now only requires you to add the new concrete File class and the appropriate case in the FileFactory implementation.

Then in your GUI you have something like:

int type = // get an int from selected type of file
File file = new ConcreteFileFactory().createFile(type);    

There are many variations to this pattern, this is just an example I adapted from Applied Java Patterns.

Upvotes: 0

Mikita Belahlazau
Mikita Belahlazau

Reputation: 15434

I'd propose to use enum for options:

enum FilePackSubclassOption {

    TYPE_A() {
        @Override
        public FilePack createFilePack() {
            return new FilePackTypeA();
        }

        @Override
        public String getName() {
            return "Type A";
        }
    };

    public abstract FilePack createFilePack();
    public abstract String getName();

    @Override
    public String toString() {
        return getName();
    }
}

To get all options you can use FilePackClassOption.values() as options parameter in JOptionPane. And when you add new subclass of FilePack your only need to add new value to enum and implement 2 methods.

Example of use:

public void chooseFilePack() {
    Object selection = JOptionPange.showInputDialog(null, 
                           "Select file pack type", "File pack", 0, null, 
                           FilePackSubclassOption.values(), null);
    if (selection != null) {
        return ((FilePackSubclassOption)selection).createFilePack();
    }
    return null;
}

Upvotes: 3

Related Questions