воскресенье, 30 марта 2014 г.

Как важны мелочи

Я переписывала пример из книги. Управление классом Cursor взял на себя класс CursorLoader. Он должен был создавать объект, приводимый к типу Loader<Cursor> и позволять с ним работать. Но сперва у меня выдавалась ошибка компиляции. Я довольно долго не понимала, в чем дело. CursorLoader к нужному классу не приводился. Я думала, что в книге опечатка. Пошла в интернет. Там то же самое. Решила, что скорее всего, что-то не так у меня в коде. И оказалось, что для CursorLoader я указала неправильный пакет. Т.е. я пыталась использовать совершенно другую функцию,  с другими возможностями. Поэтому невозможно было приведение типов. Итак, призываю себя к вниманию, вниманию и еще раз к вниманию. Одна ошибка найдена и исправлена! Но программа все равно пока не работает(.

пятница, 28 марта 2014 г.

SQL в андроиде

Для хранения данных между программными сессиями в андроид используется встроенная база данных. Каждое приложение может создать там свои таблицы и будет иметь к ним доступ. Для работы с БД есть классы ContentProvider, Cursor, SQLiteOpenHelper. Я до сих пор не разобралась, для чего их так много и что они делают. Я тупо переписываю пример из книги в программу и никак не соединю части в одно целое. Может,  это потому, что вообще тема баз данных для меня сложная, т.к. я ее нормально не успела прослушать в институте. Пока я зависла на них. Переписывание примера до сих пор не закончено. Получается все по странице из книги в день в лучшем случае. Хотя, может быть, это просто потому, что переписывание меня не вдохновляет. Нужно взять себя в руки и допереписать. А потом править то, что уже надумалось. И пробовать широковещательные приемники и вызовы сторонних программ из приложения. Почему-то это меня больше вдохновляет. Хотя эта тема для меня такой же темный лес, как и БД.

понедельник, 17 марта 2014 г.

Пометки для себя

Уже второй раз в проекте бывает, что при прекомпиляции не могут быть подключены ресурсы. Их видно, класс R генерируется, но, например, если в ресурсах цвет для собственного представления, то это представление не отображается из-за ошибки. Мне кажется, что это глюк ноутбука т.к. после перезагрузки все становится нормально.

пятница, 14 марта 2014 г.

Переопределение и перегрузка

В Java как и в C++ возможна перегрузка методов. Т.е. возможно создать методы с одинаковыми именами и с разным набором параметров, так, что выбор нужного метода определяется входными параметрами. Так же возможно переопределение родительского метода в классе-наследнике. Для переопределения необходимо, чтобы и название метода, и его параметры соответствовали классу-родителю. Иначе вместо переопределения получится перегрузка. Для того, чтобы минимизировать количество ошибок, в языке Java есть аннотация @Override. В классе-наследнике перед методом, который нужно переопределить, ставится аннотация  @Override и компилятор выдает ошибку на этапе компиляции, если вместо переопределения получается перегрузка, т.е. если параметры метода, подлежащего переопределению не соответствуют параметрам метода в родительском классе.

пятница, 7 марта 2014 г.

Конец про класс и про методы.

Надо бы поместить про класс в предыдущий пост, но блоггер почему-то выдал ошибку, при попытке дописать в пост окончание главы. Поэтому она здесь. 

 Минимизация сложности класса:
  • Включайте в класс как можно меньше методов.
  • Неявно сгенерированные методы, которые не нужны, блокируйте.
  • Минимизируйте число разных методов, вызываемых классом.
  • Избегайте опосредованных вызовов методов из других классов.
 Несколько слов о конструкторах.
Инициализируйте по возможности все данные-члены!
Если нужен класс-одиночка - используйте синглтон.
Создавайте конструктор полного копирования, если сомневаетесь - для С++ это верно. Нужно ли это в Java, я не помню(.

Причины создания класса.
  • Моделирование объектов реального мира.
  • Моделирование абстрактных объектов.
  • Снижение сложности.
  • Изоляция сложности.
  • Сокрытие деталей реализации.
  • Ограничение влияния изменений.
  • Упрощение передачи параметров в методы - если несколько методов используют одни и те же данные, вероятно, их нужно выделить в класс.
  • Создание центральных точек управления.
  • Облегчение повторного использования кода.
  • Планирование создания семейства программ.
  • Упаковка родственных операций.
  • Выполнение специфического рода рефакторинга.

Методы.

Далее в книге идет целая глава, посвященная методам.
Причины создания методов во многом такие же, как и причины создания классов. И кроме этого, есть еще несколько:
  • снижение сложности;
  • формирование понятия промежуточной абстракции;
  • предотвращение дублирования кода;
  • поддержка наследования - т.к. переопределить небольшой грамотно спроектированный метод проще, чем длинный и плохо спроектированный;
  • сокрытие очередности действий;
  • сокрытие операций над указателями - неочевидная для меня причина, но очень разумная и приводящая к простоте написания программы;
  • улучшение портируемости;
  • упрощение сложных булевых проверок - мне раньше казалось, что наличие таких проверок - это показатель "крутости" кода, но они практически нечитаемы после написания и отладки; поэтому и с этой причиной я согласна; попытаюсь впредь делать так;
  • повышение быстродействия.
Проектирование на уровне методов - проектирование методов. Методы характеризуются связностью (или силой) - соответствием выполняемых в методе операций единой цели. Самый распространенный пример хорошего метода - операция cos() или sin(). Метод cosinAndTangens() - имеет худшую связность, т.к. выполняет сразу две операции.
Цель - чтобы один метод эффективно решал одну задачу и больше ничего не делал.

Имена методов.
Имя метода должно ясно описывать все, что он делает. Т.к. ясно именовать методы в институте не учат, подробно пишу главу из книжки. Далее будет набор правил, позволяющих дать методу понятное имя. Общее правило - если метод трудно назвать, скорее всего, он плохо спроектирован.

  • Описывайте все, что метод выполняет
  • Избегайте невыразительных и неоднозначных глаголов
  • Не используйте для различия методов исключительно номера (method1 (), method2 ()...)
  • Не ограничивайте длину имени методов искусственными правилами - имя метода длиннее имени переменной; главной задачей имени является ясное и понятное описание сути метода.
  • Для именования функции используйте описание возвращаемого значения.
  • Для именования процедуры используйте выразительный глагол ( дополняя его объектом, если язык не ОО).
  • Определяйте конвенции именования часто используемых операций.
  • Дисциплинированно используйте антонимы. Т.к. это тоже одно из моих больных мест, пишу здесь часто используемые:
add/remove
begin/end
create/destroy
first/last
get/put
get/set
increment/decrement
insert/delete
lock/unlock
min/max
next/previous
old/new
open/close
show/hide
sourse/target
start/stop
up/down

Желательно, чтобы длина метода была не более 150-200 строк(без комментариев и пустот), обычно метод занимает до 100 строк. Если метод хорошо спроектирован, он уложится в эти рамки (должен).

Функцию следует использовать тогда, когда главной целью метода является возврат конкретного значения, описываемого именем функции.

Про макросы. 
Опять же, программируя на С++ я думала, что использовать макросы - это показатель крутости. Но их использование давало иногда такие ошибищи которые очень трудно было отследить и понять.  Макконнелл не рекомендует использовать макросы, кроме как в условной компиляции (он ссылается в этом на Страуструпа, а тот, видимо, знает, что говорит)).

Итак, ура. Глава, посвященная методам обработана. Надеюсь, я буду это все использовать. Очень часто при чтении этой книги у меня возникают мысли: а, как просто-то, а я... Учиться мне еще и учиться...

суббота, 1 марта 2014 г.

Наследование. Продолжение.

Наследование. Отношение "Является".
  • Убедитесь, что вы наследуете только то, что хотите наследовать. Не наследуйте реализацию только потому, что вы наследуете интерфейс. Если интерфейс класса не нужен, а нужна лишь реализация, то лучше включение, а не наследование.
  • Не используйте имена непереопределяемых методов базового класса в производных классах.
  • Перемещайте общие интерфейсы, данные и формы поведения на как можно более высокий уровень абстракции. 
  • С подозрением относитесь к классам, объекты которых создаются в единственном экземпляре. Исключение - "Одиночка".
  • С подозрением относитесь к базовым классам, имеющим только один производный класс.
  • С подозрением относитесь к класам, которые переопределяют метод, оставляя его пустым (убирая реализацию).
  • Избегайте многоуровневых иерархий наследования.
  • Предпочитайте полиморфизм, а не крупномасштабную проверку типов.
  • Множественное наследование - "инструмент, который лучше большую часть времени хранить в гараже под замком". Может пригодится, но может и порождать ошибки (ромбовидная схема!).
Правила, чтобы понять, нужно ли проектировать классы как наследники или включения.
Если несколько классов имеют общие данные, но не формы поведения, сделайте общий объект, который включите в эти классы.
Если несколько классов имеют общие формы поведения, но не данные, сделайте эти классы производными от общего базового класса, определяющего общие методы.