Это действительно подходит для Flyweight . Это в основном то, что вы пытаетесь достичь с помощью статики. С точки зрения того, как обслуживать объект Flyweight, чтобы вы не создавали тысячи из них, вот несколько идей.
Одним из них является фабрика, о которой вы заявляете, о которой думали и отвергли, хотя вы не указали, почему (так что любые другие идеи могут страдать от той же проблемы), поэтому я не буду вдаваться в подробности.
Другой вариант - иметь тип значения, имеющий метод, который может обслуживать его преобразователь. Примерно так:
public class ValueType {
public static final TextTransformable<ValueType> CONVERT = ....
}
А затем используйте это так:
ValueType value = ValueType.CONVERT.fromText(text);
String text = ValueType.CONVERT.toText(value);
Теперь это не означает, что все ValueType предоставляют свои конвертеры через один и тот же механизм, для этого, я думаю, вам нужна какая-то фабрика.
Редактировать: Я думаю, я не знаю, что вы считаете неуместным в отношении фабрики, но я думаю, что вы сосредоточены на вызывающих абонентах, так что вы чувствуете по этому поводу:
ValueType value = getTransformer(ValueType.class).fromText(text);
Вышесказанное может быть выполнено с помощью статического импорта фабрики и метода, который имеет сигнатуру, например:
public static <T> TextTransformable<T> getTransformer(Class<T> type) {
...
}
Код для поиска правильного преобразователя не обязательно самый красивый, но с точки зрения вызывающих абонентов все представлено красиво.
Редактировать 2: Думая об этом дальше, я вижу, что вы хотите контролировать построение объекта. Вы не можете этого сделать. Другими словами, в Java вы не можете заставить разработчика использовать или не использовать фабрику для создания своего объекта. Они всегда могут выставить публичного конструктора. Я думаю, что ваша проблема в том, что вы недовольны механизмами принудительного строительства. Если это понимание верно, то может пригодиться следующий шаблон.
Вы создаете объект только с закрытыми конструкторами, который переносит ваш тип значения. Объект может иметь параметр общего типа, чтобы знать, какой тип значения он переносит. Этот объект создается с помощью статического метода фабрики, который использует интерфейс фабрики для создания объекта «реального» значения. Весь код платформы, который использует объект, принимает этот объект только в качестве параметра. Он не принимает тип значения напрямую, и этот объект не может быть создан без фабрики для типа значения.
Проблема с этим подходом заключается в том, что он довольно ограничен. Существует только один способ создания объектов (поддерживаемый фабричным интерфейсом), и возможности использования объектов-значений ограничены, поскольку код, обрабатывающий эти текстовые элементы, имеет ограниченное взаимодействие только через этот объект.
Я полагаю, они говорят, что нет программной проблемы, которая не может быть решена с помощью дополнительного уровня косвенности, но это может быть слишком далеко. По крайней мере, это пища для размышлений.