2.8. Минимизация изменений в коде
Итак, необходимо, чтобы, изменяя что-либо в коде, изменялось только это, и чтобы не возникло необходимости потом изменить что-то еще.
Лучшее средство для достижения этой цели – хороший API, т.е. хорошо продуманные абстракции. Если, изменяя что-либо в коде, не изменяете API, то код клиентов менять не придется.
На самом деле не собственно API, а инкапсуляция помогает минимизировать модификации клиентского кода. Если спрятать реализацию, то она не повлияет на клиента.
Максимальная инкапсуляция хороша везде, даже внутри методов. Поэтому объявлять локальные переменные желательно ровно там, где они становятся нужны. В этом случае значение переменной, потерявшее актуальность, не испортит жизнь никому другому. Максимально локальное объявление переменных, как правило, дает следующий эффект:
Переменная не нужна — нет переменной.
Это, в частности, «развязывает руки» сборщику мусора и уменьшает зависимости между различными частями одного и того же метода.
Отсюда следует еще одно правило:
Если поле необходимо только одному методу, оно может оказаться локальной переменной.
Стоит задуматься о том, действительно ли необходимо поле — возможно, удастся обойтись локальной переменной. Поле должно описывать некоторое свойство объекта (или что-то кэшировать, но это другая история).
Более низкоуровневые средства минимизации изменений включают в себя такие идеи, как:
- Использование именованных констант. Если константа понадобится в нескольких местах программы, ее нужно сделать именованной. Вообще-то все константы лучше делать именованными — это улучшает читаемость кода, поскольку имя константы понятнее ее значения. Именованная константа дает возможность изменить значение в одном месте программы, не модифицируя больше ничего. Изменяя литералы в тысяче мест вручную, Вы можете забыть одно–два места, допустить опечатку, а можете и исправить что-то не то.
- Использование максимально абстрактных ссылок [13]. Все ссылки, используемые в программе, должны иметь настолько абстрактный тип, насколько это возможно. Если нужен список, создайте переменную типа List и присвойте ей ссылку на объект ArrayList. Если необходим LinkedList, то изменение затронет только одну строку. То же самое касается параметров, полей и прочего. Отдавайте предпочтение интерфейсам при определении типов ссылок. Интерфейс описывает абстракцию, которая необходима разработчику, а не ее реализацию. Это повышает понятность кода. Опасайтесь дырявых абстракций: задумайтесь, как может влиять реализация абстракций на работу программного обеспечения. Если не требуется список вообще, а динамический массив, используйте ссылку типа ArrayList.