4. Стандартні питання до розробника
• Що робить система, коли відбувається Х?
• Як конкретно працює функціональність Y?
• Звідки дістаються
опції Z?
• Скільки часу займе
реалізувати Х?
5. Де відповіді?
• В специфікації
• Якщо у вас вона є ;)
• В коді
• Код є завжди
• Only the Code Tells the Truth
6. В реальному житті
• Неякісний код сповільнює розробку
• Щоб дотриматись графіка, розробники
швидко пишуть неякісний код
Парадокс!
13. Константи
...
if (!resource.Exists)
{
result = HttpStatusCode.NotFound;
}
else if (resource.WasMoved)
{
result = HttpStatusCode.MovedPermanently;
}
else if (user == null)
{
result = HttpStatusCode.Unauthorized;
}
...
14. Коротке ім’я – коротка видимість
int[] elements = …
for (int i = 0; i < elements.Count(); i++)
{
elements[i] = elements[i] * 2;
}
15. Послідовні імена
• Get, Fetch, Retrieve, Obtain, Acquire
Feed feed = FeedService.ObtainSyndicationFeed();
if (feed.IsValid)
{
Storage feedStorage = GetFileStorage(path);
List<Post> posts = feed.RetrievePosts();
feedStorage.Save(posts);
}
• Виберіть одне і послідовно дотримуйтесь
його
17. Імена з предметної області
List<Person> list =
country.GetAllUnemployedPeople();
if (list.Count > 1000 * 1000)
{
presidentFacebookPage.CurrentStatus =
"Still working...";
}
18. Імена з предметної області
List<Person> unemployedPeople =
country.GetAllUnemployedPeople();
if (unemployedPeople.Count > 1000 * 1000)
{
presidentFacebookPage.CurrentStatus =
"Still working...";
}
19. Імена з предметної області
if (pageIdsByUserId.Get(user.Id)
.ContainsKey(page.Id)
) {...}
Map<int, Map<int, int>> pageIdsByUserId;
if (user.HasAccessTo(page))
{...}
20. Типові імена
• Імена змінних
customer, currentPosition, isCompleted, result
• Імена класів – іменники
Customer, UrlParser, Page, SortAlgorithm
• Імена методів – дієслова
GetCustomers(), CreateDirectory(),
OpenSocket(), Save(), Close()
26. Рівень абстракції
public void SynchronizeNewTasks()
{
string database = "DBGLOBAL";
if (user.HasAttribute("LOCAL"))
{
database = service.GetDatabaseBaseName() +
"_LOCAL";
}
if (user.Tasks.ContainsNewTasks())
{
SaveNewTasks(database, user.Tasks.GetNewTasks());
}
}
27. Рівень абстракції
public void SynchronizeNewTasks()
{
if (user.Tasks.ContainsNewTasks())
{
string database = GetDatabaseForUser(
user);
SaveNewTasks(database,
user.Tasks.GetNewTasks());
}
}
28. Аргументи функцій
• Без аргументів, Save() – найкращі :)
• Один аргумент, Send(address) – теж нічого
• Два, Copy(source, destination) – ОК
• Три – вже не дуже
• Більше – значно погіршують читабельність
:(
34. Exceptions замість кодів помилок
if (FindUserByName(userName, out user) == STATUS_OK)
{
if (Encrypt(password, out encryptedPassword) == STATUS_OK)
{
bool result = user.EncryptedPassword == encryptedPassword;
if (result)
{
if (Session.Initialize() == STATUS_OK)
return true;
else
LogError(...);
}
...
35. Обробляйте помилки
http://stackoverflow.com
...
// Catching exceptions is for communists
...
Wrong!
37. Непотрібний код
• Функції, які не ніде не використовуються –
видаляйте їх!
• Код, який ніколи не викликається –
видаляйте його!
• Історія – в системі контролю версій
38. Здоровий глузд
• Код не повинен викликати здивування
• Поведінка має бути очевидна
• «Ви працюєте з чистим кодом, якщо кожна
функція робить приблизно те, що ви
очікуєте»
42. Про коментарі
• Надавайте перевагу коду
• Коментуйте те, що не можна виразити в
коді
• Проблема коментарів – супровід
• Неточні коментарі – гірше відсутності
коментарів
• Коментарі не компенсують поганого коду
43. // check if we should redirect to another URL
if (server.HasResponse &&
server.HttpResponseCode == 301)…
vs.
bool isRedirectNeeded = server.HasResponse &&
server.HttpResponseCode == 301;
if (isRedirectNeeded)…
vs.
if (server.IsRedirectNeeded())…
44. Як коментувати
• Коментуйте публічний API
• Коментуйте внутрішній API тільки якщо він
складний
• Не використовуйте коментар там, де можна
використати функцію або змінну
• Видаляйте закоментований код
46. Single responsibility
• Класи повинні бути компактні
• Компактність визначається кількістю
відповідальностей (responsibilities)
• Клас повинен мати одну відповідальність
(single responsibility)
• Клас повинен мати одну причину для зміни
• Багато компактних класів
47. if-statements
• Чим більше if-statements, тим більше
потенційних помилок if (_serviceType == "analysis")
return 20;
public int GetHours() }
{ else //i.e. LARGE
if (_numberOfManuals <= SMALL) {
{ if (_serviceType == "writing")
if (_serviceType == "writing") return (SMALL * 30) + (20 *
return 30 * _numberOfManuals; (MEDIUM - SMALL)) + (10 *
if (_serviceType == "analysis") _numberOfManuals - MEDIUM);
return 10; if (_serviceType == "analysis")
} return 30;
else if (_numberOfManuals <= MEDIUM) }
{ return 0; //Just a default fallback
if (_serviceType == "writing") for this contrived example
return (SMALL * 30) + (20 * }
_numberOfManuals - SMALL);
50. Робота
• Робота розробника не закінчується після
того, коли програма запрацювала
• Після цього потрібно покращити структуру і
чистоту коду
51. Правило
• Дотримуйтесь «правила бойскаута»
кожен раз коли ви працюєте з кодом,
залишайте його трохи чистішим, ніж він був
до цього
52. Це просто
• Переважно неважко покращити код
• Лише трохи переіменувать, введення нових
функцій, трохи реструктуризації
• Це не rocket science
• Навіть якщо це не просто, ...
• ... це все одно цікаво
• Чому б цим не зайнятись?