Абстракция хранилища данных в J2ME

В процессе написания небольшой програмки для мобильного телефона столкнулся с тем, что работа c файловой системой (JSR-75) поддерживается не на всех телефонах. А данные надо же где-то хранить. Потому я решил реализовать поддержку записи данных как в файловую систему, так и в RecordStore

Но при этом различные объекты пишут данные по разному, поэтому в голову пришла следующая абстракция:

  • Все объекты, которые могут быть сохранены, реализуют интерфейс Storable
  • Имеется абстрактное хранилище данных, от которого наследуются реализации для файлов и для RecordStore. Это же абстрактное хранилище умеет само выбирать реализацию и выдавать ее по запросу.

Storable

Интерфейс хранимого объекта содержит три метода:
  • save(DataOutput) - сохранить объект в поток;
  • load(DataInput) - загрузить объект из потока;
  • clear() - очистить состояние объекта, вызывается в случае, если источник данных отсутствует.

package org.alnomm.storage;

import java.io.DataInput;
import java.io.DataOutput;

/**
 * Интерфейс объекта, который может быть сохранен и загружен
 * 
 * @author alno
 */
public interface Storable {

	/**
	 * Сохранить объект в поток
	 * 
	 * @param os
	 *            поток вывода данных
	 * @throws Exception
	 *             в случае ошибки
	 */
	public void save( DataOutput os ) throws Exception;

	/**
	 * Загрузить объект из потока
	 * 
	 * @param os
	 *            поток ввода данных
	 * @throws Exception
	 *             в случае ошибки
	 */
	public void load( DataInput is ) throws Exception;
	
	/**
	 * Очистить объект
	 */
	public void clear();
}

Хранилище

Хранилище - объект, отвечающий за сохранение и восстановление хранимых объектов. Для возможности доступа из произвольной точки программы, хранилище реализует паттерн синглтон. Также, хранилище исполняет обязанности по выбору необходимой реализации, т.е. работает как абстрактная фабрика. Несколько слов о выборе реализации:
  • Для того, чтобы класс ненужной реализации не загружался вообще, загрузка реализации происходит по имени класса, через механизм Reflection.
  • Для проверки поддержки JSR-75 производится попытка загрузки класса FileConnection, и если она успешна, то используется реализация на основе файловой системы, иначе на основе RecordStore.

package org.alnomm.storage;

public abstract class Storage {

	private static Storage instance = null;

	/**
	 * Получить экземпляр хранилища
	 * 
	 * @return экземпляр хранилища
	 * @throws Exception
	 *             если произошла ошибка
	 */
	public static Storage instance() throws Exception {
		if ( instance == null ) {

			String className = "org.alnomm.storage.RecordStorage"; // По умолчанию храним данные в RecordStore

			if ( hasFilesystem() ) // Если есть файловая система, то загружаем другое хранилище
				className = "org.alnomm.storage.FileStorage";

			instance = (Storage) Class.forName( className ).newInstance();
		}

		return instance;
	}

	/**
	 * Сохранить объект
	 * 
	 * @param obj
	 *            объект
	 * @throws Exception
	 *             если произошла ошибка
	 */
	public abstract void save( Storable obj ) throws Exception;

	/**
	 * Сохранить объект
	 * 
	 * @param obj
	 *            объект
	 * @throws Exception
	 *             если произошла ошибка
	 */
	public abstract void load( Storable obj ) throws Exception;

	/**
	 * Проверить, поддерживает ли телефон операции с ФС
	 * 
	 * @return
	 */
	private static boolean hasFilesystem() {
		try {
			Class.forName( "javax.microedition.io.file.FileConnection" ); // Проверяем, можем ли загругить класс
			return true;
		} catch ( Exception e ) {
			return false;
		}
	}
}

Ссылки

PS

На последок, хотелось бы задать вопрос: какие еще возможные методы хранения данных в J2ME могут быть реализованы?

 Подписаться на RSS

 #  #  #  #  #  #  #  #  #  #

Добавить комментарий