Каков наилучший способ представления свойства без гражданства, которое можно переопределить? - PullRequest
0 голосов
/ 14 декабря 2011

У меня есть абстрактный класс, который реализует некоторую функцию, скажем, FileFormat.Для каждого формата файла, который я хочу поддерживать, у меня есть подкласс, такой как ZipFileFormat или TextFileFormat.Некоторые функции формата файла с состоянием, такие как операция, чтобы преобразовать файл в поток текста.Но некоторые другие функции не имеют состояния, например расширение файла по умолчанию или префикс магического шаблона для содержимого файла.

Один из способов представить это - иметь абстрактный метод, который можно переопределить для предоставлениясвойство:

abstract String getDefaultExtension();

...

String getDefaultExtension() { return "txt"; }

Это работает, но нет способа выразить предположения базового класса об этом свойстве.В этом случае клиент API FileFormat хотел бы предположить, что возвращаемое значение getDefaultExtension() никогда не изменяется со временем.Но с переопределением нет способа объявить это намерение в подклассе или утвердить ограничение в базовом классе.

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

Другой способ - это Properties решение с типом объекта, где у вас есть структура, содержащая набор настроек, которые могут быть статическими или нет, но при этом теряется безопасность типов, документация по API и т. Д.

Есть ли другие варианты или комментарии?Благодаря.

Ответы [ 4 ]

0 голосов
/ 14 декабря 2011

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

Это даст вам ZipFileType синглтон, который вы используете во всех случаях ZipFileFormat.

0 голосов
/ 14 декабря 2011

Действительно ли распространение коротких струн действительно так важно?

Кроме того, нет отличного способа указать неизменность во времени вне самого класса, кроме как в комментарии.

Вы можете использовать константу static final и вернуть ее в метод получения, чтобы избежать повторяющихся данных. Используйте @see в Javadocs, чтобы константа и получатель ссылались друг на друга.

Не знаю, лучше ли это, чем получатель с литералом, кроме незначительной семантики.

Полагаю, вы могли бы зарегистрировать каждый подкласс самостоятельно со своим расширением.

Вы всегда можете использовать собственный доклет для предоставления дополнительной информации в Javadocs. Я также не верю, что полагаться исключительно на Javadocs - это обязательно лучшее решение.

0 голосов
/ 14 декабря 2011

Выполните оба действия: базовый класс будет иметь реализацию по умолчанию, которая возвращает значение поля, инициализированного в конструкторе. Подкласс может переопределить метод получения и добавить собственную логику. Я думаю, что проблема памяти, необходимой для хранения строки "txt" для каждого экземпляра класса, не имеет значения: вы должны хранить ее в любом случае, даже если она жестко закодирована в подклассе. А мне лично пофиг на 6 дополнительных байтов.

0 голосов
/ 14 декабря 2011

По крайней мере, для Java это не займет дополнительного места, если вы сохраните его как поле класса.

Скажем, у вас есть

String fileExtension="txt";

Вместо того, чтобы каждый экземпляр класса сохранял txt String, Java просто заставит их ссылаться на исходную копию.

Вы также можете сделать

static final String fileExtension = "txt";

Это сделало бы поле универсальным для всех экземпляров класса и не могло быть изменено (в Java Строки являются неизменяемыми. Когда я ссылаюсь на 'изменение'a String, я не имею в виду изменение отдельных символов в строке. Вместо этого fileExtension="bfr"; будет указывать fileExtension на НОВЫЙ String объект с назначенным ему значением bfr).

...