В моем приложении для Android мне нужно прочитать большой объем данных из набора файлов .ini, которые изначально (и до сих пор) были развернуты с помощью приложения Windows. Приложение предназначено для конкретного аппаратного обеспечения, а основная цель файлов .ini - описать константы программирования, данные в реальном времени и элементы пользовательского интерфейса в отношении аппаратного устройства.
Чтобы перейти к конкретному вопросу проектирования Java, я хотел бы получить помощь, вот пример того, как будет структурирована типичная строка данных из .ini файла. Обычно у нас есть имя параметра, за которым следуют различные столбцы строковых или числовых данных:
example = example, "example", "C", 0, 255, -1, -1, 256, 256
Каждая строка данных, которые я анализирую и токенизу, затем представляется в приложении как объект. Чтобы выполнить создание каждого объекта из каждой строки данных файла .ini, я в настоящее время использую интерфейс Builder/Fluent. Таким образом, вышеприведенная строка приведет к созданию объекта таким образом:
someObject.setName( t.s(2) ).setUnits( t.s(3) ).setLowerUpper( t.f(4), t.f(5) ) ...
t
- это мой экземпляр класса tokenizer, который использовался для анализа файла .ini, а его методы s(int)
и f(int)
- это получатели, которые извлекают целое число или float для данного номера столбца.
Это немного беспорядочно, потому что мой основной класс обработки файлов .ini, который выполняет создание объекта на основе данных, возвращаемых из токенизатора, должен содержать магические числа повсюду для столбцов строк. Я также должен позаботиться о том, чтобы использовать s()
или f()
, если это необходимо (хотя компилятор, конечно, сообщит об ошибке, если я использую неверный, на основе типов, необходимых для моих объектов).
Мне бы очень хотелось, чтобы у меня был другой класс, который я мог бы назвать IniFileDefinitions. В идеале этот класс будет содержать перечисляемые определения для номеров строк и связанных с ними типов. Поэтому, используя этот класс, созданное выше создание объекта может выглядеть примерно так (псевдокод, очевидно):
someObject.setName( t.get(INI_NAME) ).setUnits( t.get(INI_UNITS) ).setLowerUpper( t.get(INI_LOWER), t.get(INI_UPPER) );
Где я немного застрял, так это то, как я могу определить значение перечисления, которое я мог бы передать моему токенизатору, и чтобы токенизатор не только использовал это перечисление для определения номера столбца, но и изменял возвращаемый тип ( целое число, строка, float и т.д.) на основе этого перечисления.
Я понимаю, что перечисления Java достаточно мощные, и для меня было бы возможно иметь два поля для перечисления, где первое поле дает номер строки, а второе поле описывает тип, например:
public enum someIniEnumDefs{
INI_NAME( 2, INI_TYPE_STRING )
...
Мне пришло в голову, что способ сделать эту работу будет иметь метод getter в моем токенизаторе, который может варьировать тип, который он возвращает, в зависимости от того, какой тип перечисления должен указывать, но, очевидно, это невозможно в Java, Насколько мне известно, мне пришлось бы возвращать пользовательский объект, содержащий один из всех типов (string, integer,...) или просто вернуть Object (ugh). Мне не особенно нравится любое из этих решений.
Одна из моих идей заключалась в том, что токенизатор может иметь несколько (перегруженных) значений get() методов, каждый метод возвращает другой примитивный тип. Какой конкретный метод get() будет вызываться, может зависеть, как-то, от моего "типа" поля в определениях перечислений. Я не думаю, что я мог бы это сделать. Единственный способ, по которому я думал, состоял бы в том, чтобы разделить мои перечисления на несколько групп, представляющих разные типы, а затем мои методы tokenizer get будут перегружены следующим образом:
int get(SomeIniEnumDefs_Ints){ ... return someInt }
String get(SomeIniEnumDefs_Strings){ ... return someString }
...
Учитывая мой недостаток опыта работы с перечислениями Java (которые, как я знаю, далеки, гораздо более мощные, чем то, к чему я привык в простой старой C!), я знаю, что должен быть аккуратный способ добиться этого. Может ли кто-нибудь предложить какие-либо дополнительные указания?
Спасибо,
Трев