Сегодня в лифте услышал: "я постоянно опаздываю на Срам митинг. Если бы он хоть нормальным был, а то клуб анонимных алкоголиков: вчера пил, сегодня пью, завтра буду пить".
1. Бага первая: срам не поменяется пока перемен хочет только его ведущий.
2. Бага вторая: пил, пью, буду пить - решение тут http://egorfine.com/ru/articles/effective-meetings/
А вообще, шутка прикольная.
Двигаем в eXtreme Programming
среда, 14 апреля 2010 г.
пятница, 8 января 2010 г.
Как проверить работают лиди в паре или нет?
Вот уже второй раз я из дому через аську пытаюсь связаться с моей бывшей напарницей. И второй раз я получаю одно и то же - "мы заняты/мы бизи" :) Что это значит? А то, что она работает в паре. Это радует. Это очень радует. Раньше такого почти никогда не наблюдалось - общение в асе всегда было более приоритетным и было поводом отвлечься, отдохнуть (сужу по себе). Так что самый неэффективный способ тратить время - болтовня в асе исключается в паре. Теория работает!
суббота, 26 декабря 2009 г.
Игра под названием Рефакторинг: Метод в ООП. Extract Method. (часть 1)
Этой статьей начинается серия статей про рефакторинг [1] - изменение кода без изменения того, за чем этот код написали. Статья рассчитана на читателя, который наслышан про рефакторинг от более продвинутых напарников но сам никогда не использовал его или использовал но крайне редко; для тех, кто хотел бы копнуть вглубь и попрактиковаться; для тех, кто хотел бы добавить рефакторинг в арсенал инструментов "на каждый день". Автор основывается на двух довольно известных книгах [1, 2] с дополнением знаниями, полученными им в процессе практических экспериментов с рефакторингом. Чтобы заразить идеей потенциального читателя, предлагаю перед углублением в текст статьи посмотреть видеоролик, в котором Автор записал сеанс одного из своих рефаткорингов.
Мое знакомство с методом началось с замечания, что он должен помещаться на экран: «метод, не помещающийся на экран — плохой метод». На вопрос "почему?"я получил ответ "чтобы было удобно читателю". С тех пор прошло несколько лет.
Раньше я писал процедуры и функции. Процедура для меня была списком действий, которые должен был выполнить компьютер, чтобы "моя была довольна", а функция, к тому же, что-то возвращала. Список команд компьютеру часто был очень длинным. Иногда процедуры создавались для повторного использования кода, намного реже - для устранения дублирования.
Т.к. процедуроведение оттачивалось годами, то это хорошо отпечаталось на моем понимании ООП. Класс был просто удобным хранилищем для сходных процедур, которые я с гордостью называл методами. Редко, но некоторые из них все же использовали общие данные — поля класса. Позже пришло понимание инкапсуляции — класс не хранилище подобных процедур, а модель объекта реального мира. Методы начали рассматриваться немного иначе, но процедурный стиль не был искоренен окончательно - об этом свидетельствовала все еще большая величина методов.
Слава Байту, в моей жизни появился Рефакторинг. Он то и поставил все на свои места. Если оставлять мост между процедурным и ООП стилем, то метод — это процедура, делающая одно действие и обрабатывающая при этом данные своего объекта. Следом объявилось новое свойство методов - они выделяются не только с целью устранения дублирования [2]. Это было ценное открытие для меня. Моя эйфория по этому поводу была предметом многочисленных споров с сотрудниками во время парной разработки. «Зачем создавать метод который никогда не будет использован?!!» А затем, чтобы сделать нечто, что будет просто осуществлять одно действие и больше ничего. Если уж метод не будет востребован — сделай его приватным.
Цель этой статьи - продемонстрировать, что можно вытворять с большими методами делая процедурный код более объектно ориентированным с помощью Рефакторинга. На словах что-то объяснить сложно. В работе мне помогает парное программирование. Тут же на примере я попробую продемонстрировать базовый тип рефакторинга — выделение метода (Extract method). Я всегда ленился делать это руками, но когда я узнал, что в IDE (любой) присутствует подобная функция - я влюбился в этот тип рефакторинга. Итак, вначале был экстракт метод (Extract Method). Он же самый, как мне кажется, используемый — дорога в увлекательный мир ООП, шаблонов, рафакторинга и архитектуры.
Суть Extract Method — часть сложного метода сделать отдельным полноценным методом, после использовать делегацию (старый вызывает новый). Подобным образом мы устраняли дублирование в процедурах. Наш исходный метод (для простоты понимания выбирался довольно простой метод):
public void foo(List<String> answers) {
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.answer == Answers.DEFAULT_ANSWER) {
this.count = this.count + SOME_CONSTANT;
} else {
this.count = this. count - SOME_CONSTANT;
}
this.saveAnswer();
}
}
Первый шаг - опишем что же метод делает на родном языке. «Проходясь по всем answers, выбирает и устанавливает каждый его элемент в this.answer, а потом сравнивает это свойство с чем-то. Основываясь на результате сравнения определяет - уменьшать или увеличивать значения this.count. После выполняет некое сохранение».
Второй шаг — выделим из описания все действия (все формы глаголов).
Проходясь по всем answers, выбирает и устанавливает каждый его элемент в this.answer, а потом сравнивает это свойство с чем-то. Основываясь на результате сравнения определяет - уменьшать или увеличивать значения this.count. После выполняет некое сохранение.
Итого: проходится, выбирает, устанавливает, сравнивает, основываясь на чем-то определяет, уменьшает, увеличивает и выполняет сохранение. 7 действий на 1 метод. Многовато, если вспомнить, что наша цель - не более одного действия/глагола на метод.
Третий шаг - отделить действия, которые, по твоему мнению, более подходят для исходного метода от остальных, которые можно считать низкоуровневыми. Для этих целей я пользуюсь так называемым (мной) уровнем абстракции. Термин возможно и неудачный, но привычный для меня. Его можно переопределить по собственному желанию. Смысл в том, насколько сложные данные обрабатываются методом и/или насколько сложны действия над этими данными. Например, сложение двух чисел немного проще, чем это же сложение зависимое от условия, а цикл вносит еще немного веса в сложность.
В большом методе, скорее всего, намешано логики с разными «уровнями абстракции»: от работы с примитивами до обработки сложных типов данных; от использования операции сложения до использования каких-то специфических алгоритмов. С этим нам предстоит разобраться. В методе должна остаться только самая высокоуровневая логика - чаще всего это получается сделать.
Возьмем исходный метод и оценим отдельные его составляющие:
public void foo(List<String> answers) {
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.answer == Answers.DEFAULT_ANSWER) {
this.count = this.count + SOME_CONSTANT;
} else {
this.count = this. count - SOME_CONSTANT;
}
this.saveAnswer();
}
}
Тут красным цветом обозначена самая низкоуровневая логика (сравнивает, уменьшает, увеличивает), синим — самая высокоуровневая (проходится, выбирает), зеленый - где-то посреднике (устанавливает, сравнивает, основываясь на чем-то определяет, выполняет сохранение).
На практике чаще проще определить самую низкоуровневую операцию, но есть и исключения, когда легче выделить сразу все, что что не является самой высокоуровневой. В данном примере - можно выделить сразу тело цикла помечено красным и зеленым цветом, а можно и начать с красной низкоуровневой реализации.
Выделим низкоуровневый код:
private boolean isDefaultAnswer() {
return this.answer == Answers.DEFAULT_ANSWER;
}
priavte void increaseCounter() {
this.count = this.count + SOME_CONSTANT;
}
priavte void decreaseCounter() {
this.count = this.count – SOME_CONSTANT;
}
исходный метод немного преобразится:
public void foo(List<String> answers) {
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.isDefaultAnswer()) {
this.increaseCounter();
} else {
this.decreaseCounter();
}
this.saveAnswer();
}
}
Напомню, что выделение делается автоматически. От нас требуется выделить код, нажать гарячую клавишу, ввести название метода и нажать Enter.
Хотя сложность метода так же как и раньше определяется 7ю глаголами, теперь мы не видим реализации низкоуровненой логики. Это улучшает понимабельность кода программистом, т.к. он не видит лишней информации (которая чаще всего его отвлекает).
Идем дальше и выделим условный блок, тем самым спрячем красно-зеленую реализацию:
private void changeCounter() {
if (this.isDefaultAnswer()) {
this.increaseCounter ();
} else {
this.decreaseCounter ();
}
}
public void foo(List<String> answers) {
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
this.changeCounter();
this.saveAnswer();
}
}
Стоит отметить очень важное свойство метода — его Имя. Что есть имя метода? Это то, что скрывает реализацию. Это то, что отвечает на вопрос "что?". Реализация же — отвечает на вопрос "как?". Название метода — это и есть тот глагол, о котором мы говорили выше. Если удается создать красивое имя для метода содержащее один глагол, то это верный знак - метод выделябельный. В противном случае лучше оставить как есть.
Еще раз (это важно): название метода должно отвечать на вопрос ЧТО делает метод и содержать ОДИН глагол. Методы с названием типа doSomething1AndSomething2 – это не методы, а процедуры.
В нашем случае изменения счетчика и сохранение ответа это действия в разных плоскостях, и если удастся их объединить под красивым одноглагольным именем — супер! Мне пока не приходит ничего в голову, потому оставляем как есть.
В самом конце стоит пересмотреть имя для исходного метода foo - теперь эта задача решается программистом в разы легче.
public void processAnswers(List <String> answers) {
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
this.changeCounter();
this.saveAnswer();
}
}
Кстати, изменения названия метода (Rename method) так же частый гость, и в ИДЕ, с большей долей вероятности, она так же автоматизирована.
В этом примере нам не приходилось делать никаких действий перед выделением - мы просто выделяли нужный блок в метод. Иногда бывает, что блок не готов к выделению. Чаще всего выделению мешает локальная переменная. О ней узнаем больше в статье «Локальные переменные — зло?». Забегая наперед скажу, что нам помогут такие звери как: встраивание локальной переменной, замена локальной переменной вызовом метода, расщепление локальной переменной, введение поясняющей переменной и некоторые другие [1].
Выделение метода — отправная точка к другим типам рефакторинга. В результате у нас образовалось некоторое количество новых методов, которым, возможно, не место в этом классе (как это определять и что с этим делать расскажу в «Где моя тачка, Чувак?»). Кроме того у нас остался исходный метод processAnswers. Его как раз и предлагаю еще поковырять.
Воспользуемся для установки значения поля this.answer его сеттер (если его нет, то создадим):
public void processAnswers(List <String> answers) {
for (int index == 0; index < this.size; index ++) {
this.setAnswer(answers.get(index));
this.changeCounter();
this.saveAnswer();
}
}
Т.к. цикл проходится по всем элементам списка, то воспользуемся его сокращенной версией (ведено в Java 1.5):
public void processAnswers(List <String> answers) {
for (String answer : answers) {
this.setAnswer(answer);
this.changeCounter();
this.saveAnswer();
}
}
Вот теперь намного лучше.
После таких обработок можно заметить, что результирующий метод не использует данных исходного класса непосредственно, а значит есть шанс, что он является либо его расширением, либо частью другого класса использующего этот. Он может быть и частью исходного класса, но это должна позволять его метафора (про метафоры напишу в статье «Безымянный класс»). Все же я бы пересмотрел интерфейс изменяемого класса на всякий случай.
Вот так вот мы расправились с довольно простым методом и поняли глубже как он работает.
Продолжение следует....
Список чтива:
1. Мартин Фаулер "Рефакторинг"
2. Стив Макконнелл "Совершенный код"
Мое знакомство с методом началось с замечания, что он должен помещаться на экран: «метод, не помещающийся на экран — плохой метод». На вопрос "почему?"я получил ответ "чтобы было удобно читателю". С тех пор прошло несколько лет.
Раньше я писал процедуры и функции. Процедура для меня была списком действий, которые должен был выполнить компьютер, чтобы "моя была довольна", а функция, к тому же, что-то возвращала. Список команд компьютеру часто был очень длинным. Иногда процедуры создавались для повторного использования кода, намного реже - для устранения дублирования.
Т.к. процедуроведение оттачивалось годами, то это хорошо отпечаталось на моем понимании ООП. Класс был просто удобным хранилищем для сходных процедур, которые я с гордостью называл методами. Редко, но некоторые из них все же использовали общие данные — поля класса. Позже пришло понимание инкапсуляции — класс не хранилище подобных процедур, а модель объекта реального мира. Методы начали рассматриваться немного иначе, но процедурный стиль не был искоренен окончательно - об этом свидетельствовала все еще большая величина методов.
Слава Байту, в моей жизни появился Рефакторинг. Он то и поставил все на свои места. Если оставлять мост между процедурным и ООП стилем, то метод — это процедура, делающая одно действие и обрабатывающая при этом данные своего объекта. Следом объявилось новое свойство методов - они выделяются не только с целью устранения дублирования [2]. Это было ценное открытие для меня. Моя эйфория по этому поводу была предметом многочисленных споров с сотрудниками во время парной разработки. «Зачем создавать метод который никогда не будет использован?!!» А затем, чтобы сделать нечто, что будет просто осуществлять одно действие и больше ничего. Если уж метод не будет востребован — сделай его приватным.
Цель этой статьи - продемонстрировать, что можно вытворять с большими методами делая процедурный код более объектно ориентированным с помощью Рефакторинга. На словах что-то объяснить сложно. В работе мне помогает парное программирование. Тут же на примере я попробую продемонстрировать базовый тип рефакторинга — выделение метода (Extract method). Я всегда ленился делать это руками, но когда я узнал, что в IDE (любой) присутствует подобная функция - я влюбился в этот тип рефакторинга. Итак, вначале был экстракт метод (Extract Method). Он же самый, как мне кажется, используемый — дорога в увлекательный мир ООП, шаблонов, рафакторинга и архитектуры.
Суть Extract Method — часть сложного метода сделать отдельным полноценным методом, после использовать делегацию (старый вызывает новый). Подобным образом мы устраняли дублирование в процедурах. Наш исходный метод (для простоты понимания выбирался довольно простой метод):
public void foo(List<String>
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.answer == Answers.DEFAULT_ANSWER) {
this.count = this.count + SOME_CONSTANT;
} else {
this.count = this. count - SOME_CONSTANT;
}
this.saveAnswer();
}
}
Первый шаг - опишем что же метод делает на родном языке. «Проходясь по всем answers, выбирает и устанавливает каждый его элемент в this.answer, а потом сравнивает это свойство с чем-то. Основываясь на результате сравнения определяет - уменьшать или увеличивать значения this.count. После выполняет некое сохранение».
Второй шаг — выделим из описания все действия (все формы глаголов).
Проходясь по всем answers, выбирает и устанавливает каждый его элемент в this.answer, а потом сравнивает это свойство с чем-то. Основываясь на результате сравнения определяет - уменьшать или увеличивать значения this.count. После выполняет некое сохранение.
Итого: проходится, выбирает, устанавливает, сравнивает, основываясь на чем-то определяет, уменьшает, увеличивает и выполняет сохранение. 7 действий на 1 метод. Многовато, если вспомнить, что наша цель - не более одного действия/глагола на метод.
Третий шаг - отделить действия, которые, по твоему мнению, более подходят для исходного метода от остальных, которые можно считать низкоуровневыми. Для этих целей я пользуюсь так называемым (мной) уровнем абстракции. Термин возможно и неудачный, но привычный для меня. Его можно переопределить по собственному желанию. Смысл в том, насколько сложные данные обрабатываются методом и/или насколько сложны действия над этими данными. Например, сложение двух чисел немного проще, чем это же сложение зависимое от условия, а цикл вносит еще немного веса в сложность.
В большом методе, скорее всего, намешано логики с разными «уровнями абстракции»: от работы с примитивами до обработки сложных типов данных; от использования операции сложения до использования каких-то специфических алгоритмов. С этим нам предстоит разобраться. В методе должна остаться только самая высокоуровневая логика - чаще всего это получается сделать.
Возьмем исходный метод и оценим отдельные его составляющие:
public void foo(List<String>
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.answer == Answers.DEFAULT_ANSWER) {
this.count = this.count + SOME_CONSTANT;
} else {
this.count = this. count - SOME_CONSTANT;
}
this.saveAnswer();
}
}
Тут красным цветом обозначена самая низкоуровневая логика (сравнивает, уменьшает, увеличивает), синим — самая высокоуровневая (проходится, выбирает), зеленый - где-то посреднике (устанавливает, сравнивает, основываясь на чем-то определяет, выполняет сохранение).
На практике чаще проще определить самую низкоуровневую операцию, но есть и исключения, когда легче выделить сразу все, что что не является самой высокоуровневой. В данном примере - можно выделить сразу тело цикла помечено красным и зеленым цветом, а можно и начать с красной низкоуровневой реализации.
Выделим низкоуровневый код:
private boolean isDefaultAnswer() {
return this.answer == Answers.DEFAULT_ANSWER;
}
priavte void increaseCounter() {
this.count = this.count + SOME_CONSTANT;
}
priavte void decreaseCounter() {
this.count = this.count – SOME_CONSTANT;
}
исходный метод немного преобразится:
public void foo(List<String>
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
if (this.isDefaultAnswer()) {
this.increaseCounter();
} else {
this.decreaseCounter();
}
this.saveAnswer();
}
}
Напомню, что выделение делается автоматически. От нас требуется выделить код, нажать гарячую клавишу, ввести название метода и нажать Enter.
Хотя сложность метода так же как и раньше определяется 7ю глаголами, теперь мы не видим реализации низкоуровненой логики. Это улучшает понимабельность кода программистом, т.к. он не видит лишней информации (которая чаще всего его отвлекает).
Идем дальше и выделим условный блок, тем самым спрячем красно-зеленую реализацию:
private void changeCounter() {
if (this.isDefaultAnswer()) {
this.increaseCounter ();
} else {
this.decreaseCounter ();
}
}
public void foo(List<String>
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
this.changeCounter();
this.saveAnswer();
}
}
Стоит отметить очень важное свойство метода — его Имя. Что есть имя метода? Это то, что скрывает реализацию. Это то, что отвечает на вопрос "что?". Реализация же — отвечает на вопрос "как?". Название метода — это и есть тот глагол, о котором мы говорили выше. Если удается создать красивое имя для метода содержащее один глагол, то это верный знак - метод выделябельный. В противном случае лучше оставить как есть.
Еще раз (это важно): название метода должно отвечать на вопрос ЧТО делает метод и содержать ОДИН глагол. Методы с названием типа doSomething1AndSomething2 – это не методы, а процедуры.
В нашем случае изменения счетчика и сохранение ответа это действия в разных плоскостях, и если удастся их объединить под красивым одноглагольным именем — супер! Мне пока не приходит ничего в голову, потому оставляем как есть.
В самом конце стоит пересмотреть имя для исходного метода foo - теперь эта задача решается программистом в разы легче.
public void processAnswers(List
for (int index == 0; index < this.size; index ++) {
this.answer = answers.get(index);
this.changeCounter();
this.saveAnswer();
}
}
Кстати, изменения названия метода (Rename method) так же частый гость, и в ИДЕ, с большей долей вероятности, она так же автоматизирована.
В этом примере нам не приходилось делать никаких действий перед выделением - мы просто выделяли нужный блок в метод. Иногда бывает, что блок не готов к выделению. Чаще всего выделению мешает локальная переменная. О ней узнаем больше в статье «Локальные переменные — зло?». Забегая наперед скажу, что нам помогут такие звери как: встраивание локальной переменной, замена локальной переменной вызовом метода, расщепление локальной переменной, введение поясняющей переменной и некоторые другие [1].
Выделение метода — отправная точка к другим типам рефакторинга. В результате у нас образовалось некоторое количество новых методов, которым, возможно, не место в этом классе (как это определять и что с этим делать расскажу в «Где моя тачка, Чувак?»). Кроме того у нас остался исходный метод processAnswers. Его как раз и предлагаю еще поковырять.
Воспользуемся для установки значения поля this.answer его сеттер (если его нет, то создадим):
public void processAnswers(List
for (int index == 0; index < this.size; index ++) {
this.setAnswer(answers.get(index));
this.changeCounter();
this.saveAnswer();
}
}
Т.к. цикл проходится по всем элементам списка, то воспользуемся его сокращенной версией (ведено в Java 1.5):
public void processAnswers(List
for (String answer : answers) {
this.setAnswer(answer);
this.changeCounter();
this.saveAnswer();
}
}
Вот теперь намного лучше.
После таких обработок можно заметить, что результирующий метод не использует данных исходного класса непосредственно, а значит есть шанс, что он является либо его расширением, либо частью другого класса использующего этот. Он может быть и частью исходного класса, но это должна позволять его метафора (про метафоры напишу в статье «Безымянный класс»). Все же я бы пересмотрел интерфейс изменяемого класса на всякий случай.
Вот так вот мы расправились с довольно простым методом и поняли глубже как он работает.
Продолжение следует....
Список чтива:
1. Мартин Фаулер "Рефакторинг"
2. Стив Макконнелл "Совершенный код"
Ярлыки:
Extract method,
метод,
ООП,
парное программирование,
рефакторинг
пятница, 25 декабря 2009 г.
Метод 360 градусов
Вот хорошее описание ЧтоГдеКогдаЗачемПочемуСколько.
Увольняясь из компании решил опросить народ с тем, чтобы понять, что мне стоит укрепить, а что есть сильные мои стороны. Один из коллег меня предостерег, и не дал фидбек - ты не получишь достоверной информации напрямую. Кто-то не захочет тебя обидеть, кто-то не захочет открываться, кто-то не доверяет, кто-то недолюбливает, кто стесняется. Причин море. Вот он и посоветовал найти прокси, который собрал бы всю эту информацию. Согласилась Алечка. Спасибо большое.
Список интересующих вопросов составил сам. Вот они:
Позже, перечитав пачку статей про 360, я понял, что не все делалось правильно (скорее, в этой попытке была только общая задумка опросить всех с обеспечением анонимности), но первый опыт есть, а это всегда лучше чем тонны непроверенных знаний. Спасибо всем, кто участвовал в формировании фидбека - это на самом деле самый ценный и необычный фидбек, который я когда-либо получал.
А вот из за чего весь сыр бор:
Увольняясь из компании решил опросить народ с тем, чтобы понять, что мне стоит укрепить, а что есть сильные мои стороны. Один из коллег меня предостерег, и не дал фидбек - ты не получишь достоверной информации напрямую. Кто-то не захочет тебя обидеть, кто-то не захочет открываться, кто-то не доверяет, кто-то недолюбливает, кто стесняется. Причин море. Вот он и посоветовал найти прокси, который собрал бы всю эту информацию. Согласилась Алечка. Спасибо большое.
Список интересующих вопросов составил сам. Вот они:
1. командная работа (как работалось/что можно выделить из "+" и "-"/какие напутствия?)Когда фидбек был готов я с нетерпением его прочитал. Потом прочитал еще раз, потом еще. Странное двоякое чувство. Т.к. дока отредактирована одним человеком, кажется что фидбек давал один человек. Но на самом деле их было 5. И вот это непонятное: вроде похвалили, вроде поругали, вроде с пренебрежением и в тот же момент с любовью и благодарностью. Супер! Фидбек просто супер!
2. заметные положительные личные качества (что такого, за что хотелось бы похвалить/отметить/выделить/чтобы у всех такое было/уникальное/что придавало уверенности и желания работать вместе)
3. личные качества, которые мешали в работе (что такого, за не хотелось находиться в одной команде/вызывало тошноту/портило настроении/мешало работе/отвлекало/бесило/хотелось убить?)
4. технический уровень (как в общем/изучение нового/уровень базы/уровень ядра/уровень презентации/дизайн/на что обратить внимание?)
5. коммуникативные навыки (как в общении? что хорошо, что не очень? на что обратить внимание?)
6. вклад в Компанию (что/как было сделано такого, что можно считать личным вкладом в Компанию?)
7. непростительные ошибки (что было сделано такого, что попадает под категорию "непростительные ошибки"/возможно что-то было упущено/возможно что-то проигнорировано - что именно и почему?)
8. возможно что-то не попало ни в одну из категорий, но очень-очень-очень важное, что? и почему?
Позже, перечитав пачку статей про 360, я понял, что не все делалось правильно (скорее, в этой попытке была только общая задумка опросить всех с обеспечением анонимности), но первый опыт есть, а это всегда лучше чем тонны непроверенных знаний. Спасибо всем, кто участвовал в формировании фидбека - это на самом деле самый ценный и необычный фидбек, который я когда-либо получал.
А вот из за чего весь сыр бор:
Підтримка команди з тех сторони — добре. Покращити підтримку команди в стресових ситуаціях, брати відповідальність. Багато допомагав, направляв, намагався налагодити роботу в компанії, беручи до уваги особисті принципи, бачення, досвід багатьох книг. Спочатку відчувався командний дух, бажання зробити для команди буквально все. Останні місяці відчутне бажання усамітнитись і складалось враження про абсолютну байдужість до того, що робиться в проекті. Дуже різкий контраст між тим, що було раніше і зараз. Працелюбний, відповідальний, безкорисливий. Намагання самовдосконалитись, спроби зробити умови праці кращими, боротьба за справедливість, бажання допомогти (не важливо по роботі чи в житті). Цілеспрямованість. Недостатня відкритість, образливість (інколи через дрібниці). Намагання примусити інших працювати так, як працюєш сам. Деякі шишки потрібно набити самому. Завжди пропонується вудочка замість того, щоб вказати рибне місце. Питання через аську замість живого спілкування. Впертість, небажання іти на компроміс. Технічний рівень достатньо хороший, звернути увагу на тонкощі технологій+бази. Є великий потенціал до вивчення і засвоєння нового матеріалу. Дизайн — трохи гірше. Звернути увагу на різницю між браузерами (.js) Готовий до фідбеку, покращити живе спілкування, відкритість. Залежить від настрою, може бути дуже цікавим співрозмовником, намагається не грубити і бути терпимим до чужих образ. Звернути увагу на образливість, не варто сприймати всерйоз нападки оточуючих, вони теж люди і часом тебе не розуміють. Розвиток QA. Підвищення якості коду. TDD і рефакторинг. Звернув увагу компанії на особисті потреби працівників. Генерація ідей. Якщо говорити про соціальне — великий вклад, для багатьох ковток свіжого повітря, нові патерни, погляди на проектування, парне програмування, тестування, архітектура. Дякую за гарне програмування. Саня, не йди, нам буде тебе не вистачати!Еще раз спасибо.
пятница, 18 декабря 2009 г.
Как Петя с требованиями работал
Из википедии: "В разработке программного обеспечения, анализ
требований -- это процесс сбора требований к
программному обеспечению, их систематизации, документирования,
анализа, выявления противоречий, неполноты, разрешения конфликтов."
Жил был Петя. Жил не тужил. Игрался с компьютером. У него это получалось. Решил попробовать заработать на новый компьютер. Ничего другого не умел делать и пошел Петя программистом в компанию. Он не знал что такое коммерческий мир. Взяли Петю на работу и очень скоро Петя стал полноценным членом команды. Команда, в которой работала еще девочка Настя, мальчик Коля и дядя Юра работали над проектом уже 8 месяцев, а до этого проект писали индусы где-то год или полтора, или может не индусы то были совсем. И нашему Пете пришлось потихоньку, изо дня в день, изучать проект вместе с Настей, Колей и дядей Юрой, которые хоть и знали проект лучше Пети, но всего лишь на 8 месяцев. Был у них еще заказчик заморский, который этот проект где-то у кого-то выиграл за игрой в покер. Неважно. А индусов уволили. Бедняжки? Ничего, они потом резервные копии подняли и быстренько проект продали еще пару раз, конкурентам. Был там среди них индус Амба - его идея. На вырученные деньги он выехал заграницу и открыл там свою компанию, а через год семью к себе забрал. Но не об этом сейчас. И вот работают эти молодые бойцы и их заморский заказчик над проектом день и ночь. А все почему? Да потому что неясно что делать, вернее все думают что ясно, но заказчик-то заморский, и через три месяца получается что ничего не ясно совсем. Что-то сделали, и даже хвалятся - мол в срок успели, Петя даже премию получил и жену повел в ресторан и купил ей книгу. Она любит читать. Тем временем заказчик поглядел поглядел на проект и подумал, что-то ребята перепутали и всех уволил. Дядя Юра спился, а Настя и Коля устроились в другую компанию. Им сразу дали новый проект и они его завалили. А все потому, что думали что ясно им, а заказчик-то заморский снова попался. А Петя наш, пока работал, хорошо с заказчиком подружился. Ну очень он хотел купить себе новый компьютер. Петя не плохой, нет, он уже в первый месяц работы говорил своим напарникам - ребята мы плохо поняли заказчика, но они его не слушали. Умные все были, с многолетним опытом работы и всякими сертификатами. Не слушали, ну и ладно. А натолкнула Петю на мысль его жена, она всегда говорила - Петя! Ты у меня такой умничка!!! И он поверил. Как то раз он захотел стать еще большей умничкой пришел на работу и открыл гугл. Ввел там "как стать еще большей умничкой" и нажал "мне повезет". Гугл отправил его на блог одного бородатого дядьки. Очень похож он был на дворника местного и Петя наш решил прочитать весь блог до конца. Узнал Петя много интересного и на утро проснулся вдвойне умничкой. А как общаться с заказчиком он случайно по радио услышал, когда готовил новое блюдо по рецепту бородатого блогера. Идея была проста как двери. Спросите у заказчика чего ему надо уже сейчас и сделайте это за две недели. И тут Петя расплакался... Он просто лук нарезал. На следующий день Петя поговорил с заказчиком и предложил ему новую идею. Заказчик был старой закалки и не сразу въехал в новую идею. Но жена его была тоже умничка и посоветовала ему попробовать. Он велел Пете собрать команду и начинать. Петя связался с безработными Настей и Колей. Коля вроде работал, кажется, официантом. Нашли дядю Юру и подшили его - вроде держится. Наняли еще тестировщика и пару программистов. Тестировщик был странный, но работу делал свою превосходно. Собрались все они в комнате на совещании и к обеду придумали слово Скрам. После пошли обедать. У Насти заболел живот и ее отпустили домой пораньше. А все остальные собрались над компьютером и ознакомились с тем, что у них было. Написали заморскому заказчику и спросили, что нам тебе сделать в первую неделю? Заказчик ответил. Они сели подумали и нарисовали как это будет выглядеть. Отправили заказчику и он добавил некоторые исправления. Они немного подправили и снова отправили. Заказчик сказал, хорошо. Собрались наши программисты и разобрали что да как будет работать. Рисунок он ведь не говорит о действии. Появились вопросы, ответов на которые не было у них. Написали заказчику. А пока он отвечал начали делать то, что уже понятно. Заказчик ответил, когда освободился. Он со своей женой ехал на пару дней к теще, не знаю какие у них там тещи, но наверное хорошие. Приехал он полон идей и вспомнил что ему предлагал Петя - раз в две недели можно будет добавлять новые новшества. Обрадовался он жутко и открыл свой почтовый ящик, который на gmail.com держал.Посмотрел туда и увидел там пару вопросов от команды. Часть своих идей (или то тещины идеи были? она тоже какой-то бизнес делала, лопухи продавала вроде) рассказал сразу им, а часть оставил на потом (вернее он все им сразу расписал, а программисты уже решили что касается текущей работы, а что потом сделают). Прошло две недели и программисты отправили результат клиенту. Он посмотрел на это и сказал, хорошо. Конечно не все было так как он хотел, а еще, за две недели его кузен попал на банановом бизнесе и больше не надо будет вот той кнопки и этого окна. Ну ладно. Подсчитал заказчик сколько он потерял и успокоился. С индусами больше попадал, да и прошло тут всего две недели. Он написал письмо программистам в котором рассказал про свое новое видение. Программисты расстроились немного, потому что они уже построили долгосрочные планы на бананы, кто-то даже провел анализ всех банановых сайтов в интернете в свое свободное время. Но программисты справились с потрясением, и, от поставки к поставке, научились не ожидать и не гадать, что будет потом. Они перестали писать код на будущее и делали ровно столько, сколько надо было заказчику. Код писался, выкидывался, переписывался, снова выкидывался. А так как реализация была простой, то программистам было просто это делать. Кроме того они узнали про рефаткоринг от бородатого дворника - его сын учился в университете, а там преподавали новые заморские методики. Вот так вот они слушали заказчика, пытались понять что он хочет, делали как поняли, показывали ему результат, а потом снова слушали. В городе, котором они работали было 30 компаний. И большая часть из них работала по другому. Ну и ладно. Главное чтобы заказчик был доволен. А наш заказчик было доволен. И с нетерпением ждал когда пойдут две недели. Иногда он конечно вмешивался посреди, но программисты придумали список простых правил, одно из которых гласило - делать и думать только про то, что было решено в начале, и ничего лишнего. А еще программисты работали по двое за компьютером. Это им снова дворник посоветовал. А сын его выпустился и пришел в компанию Пети и показал еще много всяких интересных штук. Хорошо, что Петя и его команда был легок на подъем. Через год у них работало уже 200 человек. Каждый вел свой личный блог по теме работы и их всех очень уважали в мире айти. И Петя наш компьютер модный купил, и не только себе, но и в школу, в которой учился, и дворнику бородатому и сыну его и преподавателям университета. Конец.
требований -- это процесс сбора требований к
программному обеспечению, их систематизации, документирования,
анализа, выявления противоречий, неполноты, разрешения конфликтов."
Жил был Петя. Жил не тужил. Игрался с компьютером. У него это получалось. Решил попробовать заработать на новый компьютер. Ничего другого не умел делать и пошел Петя программистом в компанию. Он не знал что такое коммерческий мир. Взяли Петю на работу и очень скоро Петя стал полноценным членом команды. Команда, в которой работала еще девочка Настя, мальчик Коля и дядя Юра работали над проектом уже 8 месяцев, а до этого проект писали индусы где-то год или полтора, или может не индусы то были совсем. И нашему Пете пришлось потихоньку, изо дня в день, изучать проект вместе с Настей, Колей и дядей Юрой, которые хоть и знали проект лучше Пети, но всего лишь на 8 месяцев. Был у них еще заказчик заморский, который этот проект где-то у кого-то выиграл за игрой в покер. Неважно. А индусов уволили. Бедняжки? Ничего, они потом резервные копии подняли и быстренько проект продали еще пару раз, конкурентам. Был там среди них индус Амба - его идея. На вырученные деньги он выехал заграницу и открыл там свою компанию, а через год семью к себе забрал. Но не об этом сейчас. И вот работают эти молодые бойцы и их заморский заказчик над проектом день и ночь. А все почему? Да потому что неясно что делать, вернее все думают что ясно, но заказчик-то заморский, и через три месяца получается что ничего не ясно совсем. Что-то сделали, и даже хвалятся - мол в срок успели, Петя даже премию получил и жену повел в ресторан и купил ей книгу. Она любит читать. Тем временем заказчик поглядел поглядел на проект и подумал, что-то ребята перепутали и всех уволил. Дядя Юра спился, а Настя и Коля устроились в другую компанию. Им сразу дали новый проект и они его завалили. А все потому, что думали что ясно им, а заказчик-то заморский снова попался. А Петя наш, пока работал, хорошо с заказчиком подружился. Ну очень он хотел купить себе новый компьютер. Петя не плохой, нет, он уже в первый месяц работы говорил своим напарникам - ребята мы плохо поняли заказчика, но они его не слушали. Умные все были, с многолетним опытом работы и всякими сертификатами. Не слушали, ну и ладно. А натолкнула Петю на мысль его жена, она всегда говорила - Петя! Ты у меня такой умничка!!! И он поверил. Как то раз он захотел стать еще большей умничкой пришел на работу и открыл гугл. Ввел там "как стать еще большей умничкой" и нажал "мне повезет". Гугл отправил его на блог одного бородатого дядьки. Очень похож он был на дворника местного и Петя наш решил прочитать весь блог до конца. Узнал Петя много интересного и на утро проснулся вдвойне умничкой. А как общаться с заказчиком он случайно по радио услышал, когда готовил новое блюдо по рецепту бородатого блогера. Идея была проста как двери. Спросите у заказчика чего ему надо уже сейчас и сделайте это за две недели. И тут Петя расплакался... Он просто лук нарезал. На следующий день Петя поговорил с заказчиком и предложил ему новую идею. Заказчик был старой закалки и не сразу въехал в новую идею. Но жена его была тоже умничка и посоветовала ему попробовать. Он велел Пете собрать команду и начинать. Петя связался с безработными Настей и Колей. Коля вроде работал, кажется, официантом. Нашли дядю Юру и подшили его - вроде держится. Наняли еще тестировщика и пару программистов. Тестировщик был странный, но работу делал свою превосходно. Собрались все они в комнате на совещании и к обеду придумали слово Скрам. После пошли обедать. У Насти заболел живот и ее отпустили домой пораньше. А все остальные собрались над компьютером и ознакомились с тем, что у них было. Написали заморскому заказчику и спросили, что нам тебе сделать в первую неделю? Заказчик ответил. Они сели подумали и нарисовали как это будет выглядеть. Отправили заказчику и он добавил некоторые исправления. Они немного подправили и снова отправили. Заказчик сказал, хорошо. Собрались наши программисты и разобрали что да как будет работать. Рисунок он ведь не говорит о действии. Появились вопросы, ответов на которые не было у них. Написали заказчику. А пока он отвечал начали делать то, что уже понятно. Заказчик ответил, когда освободился. Он со своей женой ехал на пару дней к теще, не знаю какие у них там тещи, но наверное хорошие. Приехал он полон идей и вспомнил что ему предлагал Петя - раз в две недели можно будет добавлять новые новшества. Обрадовался он жутко и открыл свой почтовый ящик, который на gmail.com держал.Посмотрел туда и увидел там пару вопросов от команды. Часть своих идей (или то тещины идеи были? она тоже какой-то бизнес делала, лопухи продавала вроде) рассказал сразу им, а часть оставил на потом (вернее он все им сразу расписал, а программисты уже решили что касается текущей работы, а что потом сделают). Прошло две недели и программисты отправили результат клиенту. Он посмотрел на это и сказал, хорошо. Конечно не все было так как он хотел, а еще, за две недели его кузен попал на банановом бизнесе и больше не надо будет вот той кнопки и этого окна. Ну ладно. Подсчитал заказчик сколько он потерял и успокоился. С индусами больше попадал, да и прошло тут всего две недели. Он написал письмо программистам в котором рассказал про свое новое видение. Программисты расстроились немного, потому что они уже построили долгосрочные планы на бананы, кто-то даже провел анализ всех банановых сайтов в интернете в свое свободное время. Но программисты справились с потрясением, и, от поставки к поставке, научились не ожидать и не гадать, что будет потом. Они перестали писать код на будущее и делали ровно столько, сколько надо было заказчику. Код писался, выкидывался, переписывался, снова выкидывался. А так как реализация была простой, то программистам было просто это делать. Кроме того они узнали про рефаткоринг от бородатого дворника - его сын учился в университете, а там преподавали новые заморские методики. Вот так вот они слушали заказчика, пытались понять что он хочет, делали как поняли, показывали ему результат, а потом снова слушали. В городе, котором они работали было 30 компаний. И большая часть из них работала по другому. Ну и ладно. Главное чтобы заказчик был доволен. А наш заказчик было доволен. И с нетерпением ждал когда пойдут две недели. Иногда он конечно вмешивался посреди, но программисты придумали список простых правил, одно из которых гласило - делать и думать только про то, что было решено в начале, и ничего лишнего. А еще программисты работали по двое за компьютером. Это им снова дворник посоветовал. А сын его выпустился и пришел в компанию Пети и показал еще много всяких интересных штук. Хорошо, что Петя и его команда был легок на подъем. Через год у них работало уже 200 человек. Каждый вел свой личный блог по теме работы и их всех очень уважали в мире айти. И Петя наш компьютер модный купил, и не только себе, но и в школу, в которой учился, и дворнику бородатому и сыну его и преподавателям университета. Конец.
Как перейти от классического программирования к парному?
Сегодня, проглядывая почту, наткнулся на письмо, которое выслал команде как предложение по решению проблемы. Это было больше года назад. Я его перечитал и приятно удивился, все что я писал - многое из того сошлось и теперь я более чем уверен, что это подойдет команде. Вот письмо:
"Тим, прошу прочитать эту статью, как вводный курс в эти дебри :) Статья наверное самая стаящая что я читал по этой теме (всего где-то 20) но длиннная.
http://www.google.com.ua/url?sa=t&sourc ... bRV1GGCn0Q
Если нету времени или же по каким-то другим причинам не удается этого сделать, то ничего не поделать - риллайф.
Дальше письмо можно не читать (многа букофф).
Это всего лишь мои мысли, они не претендуют на идеальность. Это всего лишь стартап для обсуждения, наработки. Последнее слово всеравно за тимом - на пленниге все решим.
Сережа прав - внедрение в команду чего-то ногового занимает много времени, которого к сожалению у нас сейчас катастрофически мало. У нас сразу мало что получился. Посади Тоху с Натахой, Колю со мной или Иру с Сережей и в первый день результатов будет сравнительно немного а нервов напротив. Но спешу успокоить - это длится не долго. Мы уже довольно неплохо сформированная команда и знаем про личные качества друг друга не по наслышке.
Первым что у нас может получиться - это не парный программинг а партнерский программинг. Это что-то похожее на то что говорил Сережа: начало вместе, потом когда разработка пошла каждый за своим таском, а результат перед коммитом снова вместе. Но это уже и так неформально есть сейчас - кто не пользовлся магоческим заклинанием "можешь подойти?" в чате.
Чтобы сделать качественно качественно иной шаг в сторону программирования парами можно попробовать следующее: когда звучит магическое "можешь подойти", то все не заканчивается простым советом, а продолжается до коммита (пара вместе кодят до ближайшего коммита, даже если после ответа на вопрос все очевидно). Тут будет стимул сделать коммит быстрее (а такое возможно).
Если вопросов нет, и как бы разработка идет. То можно спонтанно попроситься к кому-то посидеть покодить рядом. С этого можно стартовать рабочий день (валшебный пендель) или же сразу после обеда.
А можно пойти дальше и сделать так.
Нас честверо кодеров + пара дизайнеров. Наталка, Тоха, Коля и Я.
Андрей и Сережа ссори что не внес в список - вы очень заняты чтобы решить задачу о программинге парами тривиально.
Ирка и Артур вы сами можете решить как вам взаимодейтвовать, я незнаю как работают дизайнера и возможнно ли применить парную разработку в вашем деле.
Кстати QA: Жека и Винни тоже могут попробовать тестить парой. Но это надо обсудить с ними.
Так вот что касается 4х основных разработчиков: работаем парами. Каждый день формируется одна пара. Например Коля + Наташа утром до обеда работают над задачей Коля а потом после работают над задачей Наташи. Типа: "ты мне я тебе". На следующий день пары меняются. Коля уже может быть с Тохой.
Что делать с пленнингом? Получается попугаев (идеальных часов) у нас становится вдвое меньше. Так только кажется. Реалько мы сможем это узнать (посчитать коефициент завершенности) после деливери.
Можно (классически) взять задач на деливери столько, сколько каждый бы запленил если бы вел разработку сам, тогда фича привязывается к кому-то как и прежде.
Получается по пол дня на твою фичу. Страшно? А кто сказал что будет просто? Посмотрим в конце как справимся.
Очевидная проблема - необходимы таски кратные дню. Если таск вылазит - стоит два или три дня, то выход один - дробить. Пленнинг проделать совместно так, чтобы каждый день можно было получать какой-то результат.
Если это неудастся, то можно увеличить время итерации разработки парой с пол дня на день. То есть сегодня я с Наташей ее задачу, а завтра Наташа со мной мою. Можно так же еще увеличить время итерации и работать с одной парой вплоть до половины деливери. Можно пару не менять, а можно менять часто. Параметров для манипулирования много. Выбор велик - подберем по настроению.
Что касается самого парного программинга, то тут могу предложить только то, что мы успешно опробовали с Тохой.
Роли две: 1. кто непосредственно кодит подзадачу. 2. кто ведет лог подзадач и смотрит за тем что делает первый стараясь не вмешиваться до тех пор, пока все идет пучком.
При выполнении всех подзадач - таск можно сдавать КьюА.
Если какая-то подзадача появляется (баг/фича) - ее тут же заносят в список и продолжают прерванную подзадачу.
Когда кто-то утомляется от его роли или малокомпетентен в данной области, то можно поменяться местами.
При завершении подзадачи она вычеркивается из списка и после возможного совместного перерыва на выполнение поступает следующая подзадача с наивысшим приоритетом.
Список потом можно дать КьюА как контрольный, а можно написать приемочные тесты.
Если ктому-то что-то непонятно то разработка прерывается и устранябтся все разногласия.
Если подзадача занимает много времени, или кто-то начинает зевать - верный знак что пошли не тем путем. Перерывчик и снова в путь.
Самое сложное - не спорить. Спор занимает много времени и скорее всего не приведет к нужному результату. Спорный таск посжно отложить и обсудить на перерыве.
Вроде как все. :) Спасибо что дочитал до конца.
"Одна голова хорошо, а две лучше"
У нас все получится. Если, конечно, мы готовы к экспериментам."
Демо и фидбек по результатам деливери
Удивительно как быстро прошло демо. 20-30 кликов вышкой и все :) А сколько писали его.
У продактовнера фидбек - "классно, что все сделали". На самом деле это потолок. Большую оценку мы получить не могли - сделали то, что обещали. Быть может, если бы он знал что было внутри. Хотя это уже и не важно, ведь об этом знают как минимум двое человек я и напарница. А вот и ее фидбек, который она написала по моей просьбе:
После демо у меня был личный разговор с продактовнером (он же топ-менеджер компании), где я еще раз предложил округлить команду до 4х разработчиков, дабы были две пары и никто не страдал. Так же я явно связал результаты деливери с тем, что мы приняли с напарниц ей в ее начале. В ответ получил "аптую", что значит делайте как считаете нужным. И "главное результат - сделайте то, что пообещали". Так что будем посмотреть...
Сегодня мы решили отдохнуть друг от друга и разбежались по своим углам. Мы пробовали взять еще один рантайм таск из мантиса, но остановились - мне без пленинга сложно а у напарницы свои причины. Да и надо же все таки почитать хабрахабр и восстановить силы. Почты тоже собралось за две недели предостаточно. Да и статью по рефакторингу хочу дописать. Так что перекур.
Спасибо Оля (так зовут напарницу), за такое замечательное деливери.
У продактовнера фидбек - "классно, что все сделали". На самом деле это потолок. Большую оценку мы получить не могли - сделали то, что обещали. Быть может, если бы он знал что было внутри. Хотя это уже и не важно, ведь об этом знают как минимум двое человек я и напарница. А вот и ее фидбек, который она написала по моей просьбе:
"Враження в цілому позитивні. Хочу вказати на кілька моментів, що свідчать, що парне програмування все-таки ефективне.
Таск був вибраний важкий і давно відкладався, оскільки ніхто повної картини про те, де і що саме потрібно буде змінювати, не мав.
Перше, що заставляло працювати ефективніше, це те що постіно знаходячись вдвох за одним компом з іншою людиною, не хватає часу і, скажем так, "наглості" відволікатись на інші завдання, в той час як інша людина всіма силами старається розібратися в програмі. Так що перший і великий плюс - зводиться до мінімуму відволікання на інші сторонні "подразники".
Інша сторона - двоє людей завжди бачать одні і ті ж таски трохи під іншим кутом. Тобто якщо одного більше цікавить щоб код запрацював як можна швидше з мінімумом змін, а іншого - якість і читабельність коду - то звичайно, кожен з нас буде слідкувати за тим, щоб код відповідав його вимогам. Відповідно в результаті отримали читабельний і функціональний код.
Оскільки в різний час частини коду, з яким прийшлось працювати, написаний давно, багато з того що було зрозуміло одному з нас, зовсім не очевидно було іншому. При детальному розборі таких місць досить часто виявлялись непотрібні операції і місця де були помилки, які при звичайному тестуванні виявити було досить складно.
Також один одного завжди доповнювали інформацією (немає двох людей, які б володіли абсолютно однаковою інформацією, хтось завжди в одній області знає більше, в іншій менше). Відповідно підвищується технічний рівень.
Особисто я багато дізналась про ейджібі та можливості екліпса. В результаті таск, який я б, навіть із зараз уже здобутими знаннями, робила б напевно тижнів зо три (і не факт. що всі моменти було б враховано), було зроблено за тиждень.
З негативних вражень - то тут тільки фізично зразу важко працювати в такому темпі. Через кілька днів звикла. І трошки психологічно - досить часто відчувала себе як на екзамені - ти щось пишеш і наперед не знаєш як тебе оцінять, відмінність лиш у тому, що оцінюють зразу і виправляють зразу, а отже і помилок робиться менше."
После демо у меня был личный разговор с продактовнером (он же топ-менеджер компании), где я еще раз предложил округлить команду до 4х разработчиков, дабы были две пары и никто не страдал. Так же я явно связал результаты деливери с тем, что мы приняли с напарниц ей в ее начале. В ответ получил "аптую", что значит делайте как считаете нужным. И "главное результат - сделайте то, что пообещали". Так что будем посмотреть...
Сегодня мы решили отдохнуть друг от друга и разбежались по своим углам. Мы пробовали взять еще один рантайм таск из мантиса, но остановились - мне без пленинга сложно а у напарницы свои причины. Да и надо же все таки почитать хабрахабр и восстановить силы. Почты тоже собралось за две недели предостаточно. Да и статью по рефакторингу хочу дописать. Так что перекур.
Спасибо Оля (так зовут напарницу), за такое замечательное деливери.
Ярлыки:
демо,
отдых,
парное программирование,
стратегия,
фидбек
Подписаться на:
Сообщения (Atom)
