Сайт Игоря Кононученко   Статьи

Симметрия кода

17 ноября 2008

Прочитал книгу Кента Бека «Implementation Patterns», у нас почему-то названную «Шаблоны интеграции корпоративных приложений». Коэффициент полезного содержания в этой книге, по какой-то причине, оказался меньшим чем я рассчитывал (возможно, прочитанное будет вылазить из недр сознания позже).

Тем не менее, мысль о симметрии в коде, мне понравилась. Возможно, термин «однородность кода» ходит где-то рядом.

Симметричный код читать легче. Например, зная один метод, можно предположить, что ему есть пара: enable, disable; add, remove; undo, redo и так далее. Симметричность может проявляться не только в именах-антонимах, но и в логике кода.

Возьму книжный пример (вдобавок мое вольное изложение на основе воспринятого):

1
2
3
4
5
void process () {
  input ();
  count++;
  output ();
}

Код не симметричен: count++ дает слишком много детализации по сравнению с input и output.

1
2
3
4
5
void process () {
  input (); - ввод 
  incrementCount (); - увеличить количество
  output (); - вывод
}
Теперь более симметрично. Но ввод, увеличить количество, вывод - не самые симметричные вещи. Куда однороднее звучит - ввод, счет, вывод.

1
2
3
4
5
void process() {
  input ();
  tally ();
  output ();
}

Теперь попробую применить к своему коду (внимание, эксперементальный юмор):

Джаваскриптовый метод, создающий штмл для вывода городов в выпадающем списке.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
renderCities:function(cities)
{
	
	var options = []
	options.push(this.optionTemplate.evaluate({id:"", name: "---------"}));
	for(var i=0;i<cities.length;i++)
	{
		var city = cities[i];
		options.push(this.optionTemplate.evaluate(city));
	}
	this.cbCity.innerHTML = options.join("");
			
}
Подозреваю, с точки зрения симметрии не самый лучший код, попробую его улучшить (выношу инициализацию, выношу заполнение, делаю обновление списка):

Промежуточная версия кода была бы куда менее близка к симметрии:

1
2
3
4
5
6
renderCities:function(cities)
{
	var options = this.getInitializedOptions();
	this.fillOptionsArray(options);
	this.cbCity.innerHTML = options.join("");     			
}

А вот финальная версия, с точки зрения детализации, является симметричной:

1
2
3
4
5
6
renderCities:function(cities)
{
	var options = this.getInitializedOptions();
	this.fillOptionsArray(options);
	this.updateCitySelect(options);     			
}

Python yield — простым языком
Динамические запросы (фильтры) в django
Ctrl
Значение поля формы в Django-шаблоне
Анализируя JavaScript код