Riodevista
@Riodevista

Как правильно организовать хранение объектов в Android приложении?

Здравствуйте!

Пишу небольшое приложение под Андроид — простенький органайзер
Есть заметки, у которых в свою очередь есть атрибуты, вроде времени и даты напоминания, какого-то текста, аудизаписи, может быть.
Не могу решить, как лучше организовать их хранение.
Можно сделать таблицу в базе данных для них, где будут соответствующие поля "время", "дата", "текст", "путь к файлу" (Тогда отслеживать, что он остался прежним).
Но мне кажется, что такой подход не совсем верный, ведь напоминания — это объекты, с которыми удобно было бы работать, непосредственно обращаясь к ним, вызывая методы, например, note1.delete().
Как решить эту задачу с помощью объектов я не представляю. Допустим, в приложении мы создали таких несколько, но как быть дальше? Надо их где-то хранить. В той же базе данных? Тогда при запуске потребуется их вновь инициализировать. Или этот процесс не так страшен? Но в таком случае достаточно написать методы, которые работают с таблицей так же, как работали бы с объектами, но с той лишь разницей, что им в качестве аргумента передаём ещё id строчки в таблице, которая будет "псевдообъектом", например, deleteNote(1).

Как же сделать лучше? Может, есть другие подходы?
  • Вопрос задан
  • 4527 просмотров
Решения вопроса 1
AlPsc
@AlPsc
Java/high load/big data
Во-первых, судя по вашему описанию предметной области задачи (всего один тип объектов, фиксированный набор атрибутов объекта), база данных – то, что вам нужно. Не надо бояться инициализации объектов, потому что способа избежать восстановления объекта из хранилища (какое бы оно ни было) в данном случае нет: храните в базе – придётся инициализировать объект значениями столбцов таблицы; храните, скажем, в JSON – придётся инициализировать объект значениями, полученными из JSON-объекта (что, кстати, ещё менее удобно); используете Java-сериализацию – и там тоже будут накладные расходы на восстановление объекта из формата, в котором вы его сохранили, ну и так далее. А БД – очень удобный формат. К тому же, никто вас не заставляет инициализировать все-все объекты на старте программы: если у пользователя очень много заметок, то можно просто подгружать новые по мере листания списка.
Во-вторых, по поводу
напоминания — это объекты, с которыми удобно было бы работать, непосредственно обращаясь к ним, вызывая методы

Есть такая вещь, как single responsibility principleто же самое на русском), суть которой вкратце состоит в том, что класс должен выполнять только конкретный ограниченный круг обязанностей, и больше ничего. В данном случае ваша ошибка в том, что вы думаете о том, чтобы дать классу заметки обязанности, которые ему по идее не свойственны. Заметка в данном случае – просто сущность, отображающая хранимые данные, больше ничего, и она ничего не должна знать об уровне хранения и т.п. Так что методов типа delete(), save() и подобных у неё точно не должно быть. А вам для удобства хранения и загрузки объектов я предлагаю сделать отдельный класс типа такого (написано на коленке просто чтобы передать идею):
public class NotesManager {
       private final SQLiteDatabase db;

       public NotesManager(SQLiteDatabase db) { this.db = db; }

       public Note findById(int noteId) {
              Cursor c = db.query(...);
              //тут чтение в локальные переменные значений
              //отдельных полей из курсора,
              //если он вернул какой-то результат
              return new Note(...ранее считанные значения полей как аргументы конструктора...);
       }

       public void save(...перечисление полей...) {
              //после проверки введённых данных делаете 
              //insert в базу с переданными значениями полей 
       }
}

Также вам понадобятся методы create и delete, но если вы поняли идею, то наверняка справитесь :) Задавайте ещё вопросы, если что-то непонятно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@dplsoft
Можно сделать таблицу в базе данных для них, где будут соответствующие поля "время", "дата", "текст", "путь к файлу" (Тогда отслеживать, что он остался прежним).
Но мне кажется, что такой подход не совсем верный, ведь напоминания — это объекты, с которыми удобно было бы работать, непосредственно обращаясь к ним, вызывая методы, например, note1.delete().
Как решить эту задачу с помощью объектов я не представляю. Допустим, в приложении мы создали таких несколько, но как быть дальше? Надо их где-то хранить. В той же базе данных?


Если вам удобно (да так в принципе и правильно, хотя и медленнее) работать с объектами а не с записями в БД - то для таких вещей есть такая штука как ORM. (у вас конечно простой случай, и потому работать с записями в вашем проекте - самое то. И тем более - если вы новичок - стоит разобраться с тем, как работать с БД напрямую. Но вообще, как только сделаете учебный проект с БД - , стоит понять, что в других сложных проектах - проблем с БД будет гораздо больше и будет сложнее и лучше осваиваться с "промышленными подходами")

В общем есть ORM. Если расшифровывать - это "модель/правила" которая/которые позволяют вам сохранять состояния объектов в БД и восстанавливать их.
А на практике - это набор классом которые делают за вас всю черновую работу по взаимодействию с БД (или тем хранилищем которое под ними лежит). И вы работаете не с БД, а с некой абстракцией, которая скрывает от вас что где и как она хранит в БД или том хранилище, которая ORM использует.

Т.е. вы говорите что-то типа - "О, мой ORM! дай мне объект типа 'МояЗаметка' c идентификатором 12345!" и он сам лезет куда-то в БД (куда именно - это его личные проблемы) и отдает вам обхект класса МояЗаметка которая заполнена данными заметки с номером 12345. А дальше - "чо хошь с ним, то и делай".

А как сделал все что надо (дургая его методы, меняя свойства или как ещё), - отдаешь его обратно своему ORM-слою ( ORM можно рассматривать как слой абстракции над БД или любым другим хранилищем ) - типа "на вот тебе объект, сохрани его в БД." - и механизмы ORM делают всю черновую работу по генерации SQL-запросов и всего прочего за вас.

В зависимости от того что от орм хотели создатели, ORM может или нет управлять структурой БД или пытаться вытаскивать свои объекты из ранее созданной структуры; управлять метаданными ваших объектов и (например) содержать или нет данные о том, как эти свойства надо отображать или нет.

В некоторых ORM есть кодогенератор - т.е. вы даете ему описания классов, а он вам генерирует код, который сохраняет классы в БД и восстанавливает оттуда. Часть ORM-механизмов работтают отталкиваясь от аннотаций - т.е. вы над каждым из полей которые хотите сохранять в БД надписываете его имя, тип, индексацию и другие параметры - так например делает Persistence API - но его нет на Андроиде, потому это не наш случай (да и работа через рефлекшен считается медленной).

Ещё могу дать 2 ссылки - на сравнительную статью ОРМ для Андроид и на мой сосбвтенный ОРМ-велосипед :
www.ninthavenue.com.au/android-orm-jpa
https://gitorious.org/unat/pages/SimpleORM_Overvie...
(последнее - "на правах рекламы". творение моё, но давно не обновлявшееся в публичной репе. Сейчас много изменений, как сдаим текущий проект - опубликую что поновее. В принципе, не столько для пользования, сколько вам - для освоения идей и выдачи конструктивной критики и вопросов. если что - спрашивайте - по UnAT я вам расскажу всё)))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы