Начнем с простого примера - игры в крестики-нолики. Во-первых, в игре есть сетка 3x3, на которой два игрока поочередно ставят O и X (также известные как крестики-нолики). Игрок, который захватывает 3 последовательных плитки по горизонтали, вертикали или диагонали, выигрывает игру.

Теперь, когда мы установили основы, давайте создадим простой пользовательский интерфейс на Android. Макет состоит из 9 кнопок, расположенных в порядке 3x3. Каждый раз, когда пользователь нажимает на одну из этих кнопок, мы должны сообщить игровой логике, какая кнопка была нажата. Ничего сложного, ничего нового, просто прямолинейная реализация.

Каждая кнопка имеет идентификатор и привязана к методу onTicTacToeTileClick(View) с помощью аннотации @OnClick Butter Knife. Внутри метода мы получаем идентификатор нажатой кнопки и преобразуем его в информацию, понятную игровой логике. Это все. Теперь давайте рассмотрим несколько различных способов решения этой проблемы.

Лестницы (if … else)

if … else - одна из структур потока управления, которая может помочь нам в этом сценарии. Однако при большом количестве условий он может стать действительно многословным.

Обратите внимание, что в приведенном выше примере я усек условия для кнопок в строках 2 и 3, начиная с строки 16, для краткости.

Я также хотел бы констатировать тот факт, что в структуре управления if … else или в этом подходе нет ничего плохого. Это один из верных способов решить возникшую проблему. Однако бывают случаи, когда внесение изменений может стать неинтуитивным или может ухудшить удобочитаемость.

Переключатели

Управляющая структура switch также подходит для решения этой проблемы. Он менее подробный и более удобочитаемый, чем его if … else аналог. Опять же, в этом подходе тоже нет ничего плохого.

Анонимные структуры данных

Теперь, помимо использования if … else и switch, есть еще один способ справиться с этой ситуацией - структуры анонимных данных. Чтобы это работало, мы выбираем подходящую структуру данных, расширяем ее анонимно и используем блок инициализатора для ее заполнения.

В следующем примере используется HashMap<Integer, Pair<Integer, Integer>>, ключами которого являются идентификаторы представления, а значениями - координаты кнопки (индекс строки, индекс столбца).

В модифицированном методе onTicTacToeTileClick(View) мы получаем идентификатор нажатой кнопки, а затем пытаемся получить координату кнопки из HashMap. Этот код более читабелен и проще в обслуживании.

Проверка null в строке 7 эквивалентна последней части else в if … else релейной диаграмме или случаю default в структуре управления switch.

Когда ключи являются целыми числами, я предпочитаю SparseArray реализации на Android Map .

Также следует отметить, что всегда есть компромиссы. Использование структуры данных приводит к дополнительным требованиям к памяти, которые в большинстве случаев должны быть тривиальными. Если для вашей структуры данных требуется большое время извлечения и производительность вызывает беспокойство, этот шаблон может не подходить.

Этот шаблон действительно проявляется при использовании с функциональными интерфейсами, лямбда-выражениями и ссылками на методы. Он также может инкапсулировать и предоставлять элегантные абстракции в определенных сценариях.

Если вам понравилась эта статья, нажмите ниже.