Заводы в Java без оператора switch

Я пытаюсь построить объект фабрики, но не могу найти хороший способ сделать это в Java.

Приложение, которое я пишу, используется для обработки файлов в различных форматах, поэтому существует CodecInterface, который применяется ко всем классам, которые используются для чтения и записи файлов. Давайте предположим, что это определяет следующие методы. Каждый из этих файлов имеет уникальную назначенную человеком строку идентификатора, которая используется для идентификации кодировщика \ декодера.

String read();
void write(String data);
String getID();

Класс фабрики будет иметь метод create, который предназначен для создания экземпляров этих классов кодеков. Я полагаю, что подпись метода будет выглядеть примерно так.

static CodecInterface CodecFactory.create(String filename, String codecid, String args);

Имя файла - это имя файла для чтения / записи, а кодекид - это уникальный идентификатор, указывающий, какой кодек использовать. Параметр args представляет собой строку аргументов, передаваемых генерируемому объекту декодера / кодера. Возвращаемое значение должно быть экземпляром запрошенного объекта кодека.

Все примеры Factory, которые я видел, обычно содержат инструкцию switch внутри метода create, который создает экземпляр объекта в зависимости от идентификатора. Я хочу избежать этого, так как это не кажется правильным, и это также означает, что список более или менее фиксирован, если вы не измените метод create. В идеале я хотел бы использовать что-то вроде словаря (индексируемого идентификатором кодека), который содержит что-то, что можно использовать для создания экземпляра классов кодека, которые я хочу (я назову этот загадочный класс ClassReference). Снова, чтобы использовать некоторый квази-Java-код, вот то, что я думал как тело для метода создания.

static Dictionary<String, ClassReference>;

static CodecInterface CodecFactory.create(String filename, String codecid, String args);
{
    ClassReference classreference;

    classreference = codeclibrary(codecid);

    return classreference.instanceOf(args);
}

Словарь идентификаторов достаточно прост, но я не могу понять, каким должен быть ClassReference. Ссылка на класс должна позволить мне создать экземпляр нужного класса, как в примере выше.

Посмотрев вокруг в Интернете, метод класса и instanceOf, похоже, движутся в правильном направлении, но я не нашел ничего, что бы соединило их вместе. Как дополнительная сложность, конструкторы для создаваемых объектов будут иметь аргументы.

Любые советы о том, что я должен смотреть на, будет принята с благодарностью.

Заранее спасибо.

РЕШЕНИЕ

Спасибо всем за ваш совет. В итоге я взял кусочки из всех ваших предложений и придумал следующее, которое, кажется, работает так, как я хотел.

Обратите внимание, что я пропустил большую часть кода проверки работоспособности \ ошибок, чтобы показать важные биты.

import java.lang.reflect.Constructor;
import java.util.HashMap;

public class CodecFactory
{
    private static HashMap<String, Class<? extends CodecInterface>> codecs;

    static
    {        
        codecs = new HashMap<String, Class<? extends CodecInterface>>();

        //Register built-in codecs here
        register("codecA", CodecA.class);
        register("codecB", CodecB.class);
        register("codecC", CodecC.class);
    }

    public static void register(String id, Class<? extends CodecInterface> codec)
    {
        Class<? extends CodecInterface> existing;

        existing = codecs.get(id);        
        if(existing == null)
        {
          codecs.put(id, codec);
        }
        else
        {
          //Duplicate ID error handling
        }
    }

    public static CodecInterface create(String codecid, String filename, String mode, String arguments)
    {
        Class<? extends CodecInterface> codecclass;
        CodecInterface codec;
        Constructor constructor;

        codec = null;

        codecclass = codecs.get(codecid);
        if(codecclass != null)
        {
          try
          {
            constructor = codecclass.getDeclaredConstructor(String.class, String.class, String.class, String.class);
            codec = (CodecInterface)(constructor.newInstance(codecid, filename, mode, arguments));
          }
          catch(Exception e)
          {
            //Error handling for constructor/instantiation
          }
        }

        return codec;
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос