cpp-2013 #20 best practices

39
Практики написання коду

Upload: eleks-developers-courses-if

Post on 13-Dec-2014

1.608 views

Category:

Documents


4 download

DESCRIPTION

 

TRANSCRIPT

Page 1: cpp-2013 #20 Best practices

Практики написання коду

Page 2: cpp-2013 #20 Best practices

Simple

http://www.infoq.com/presentations/Simple-Made-Easy

Page 4: cpp-2013 #20 Best practices

vector<vector<int>> getData(){ vector<vector<int>> vector1; for (auto x = vector.begin();

x != vector.end(); ++x) { if (x->at(0) == 4) { vector1.push_back(*x); } } return vector1;}

Це може бути легко(для вас)(зараз)

http://amzn.com/0132350882

Page 5: cpp-2013 #20 Best practices

http://amzn.com/0132350882

vector<vector<int>> getFlaggedCells(){ vector<vector<int>> flaggedCells; for (auto cell : gameBoard) { if (cell.at(STATUS) == FLAGGED) { flaggedCells.push_back(cell); } } return flaggedCells;}

Цей код легший для розуміння

Page 6: cpp-2013 #20 Best practices

vector<Cell> getFlaggedCells(){ vector<Cell> flaggedCells; for (auto cell : gameBoard) { if (cell.isFlagged()) { flaggedCells.push_back(cell); } } return flaggedCells;}

Цей код легший і простіший!

Page 7: cpp-2013 #20 Best practices

Цей код простіший

vector<Cell> getFlaggedCells(){ vector<Cell> flaggedCells; copy_if( begin(gameBoard), end(gameBoard), back_inserter(flaggedCells), [](Cell cell) { return cell.isFlagged(); }); return flaggedCells;}

Page 8: cpp-2013 #20 Best practices

Простота і складність об’єктивні і абсолютніЛегкість і важкість суб’єктивні і відносніСкладно – коли функція відповідає за декілька концепцій:

Що + ЯкI/O + бізнес правилаБД + бізнес правилаConcurrency + domain…

Page 9: cpp-2013 #20 Best practices

Idiomatic code

http://herbsutter.com/elements-of-modern-c-style/

Page 10: cpp-2013 #20 Best practices

Least surprise

http://en.wikipedia.org/wiki/Principle_of_least_astonishment

Page 11: cpp-2013 #20 Best practices

http://fomuvi.ru/zadachki/raznoobraznye-zadachki/xudozhnik-i-proxozhij.html

Page 12: cpp-2013 #20 Best practices

http://fomuvi.ru/zadachki/raznoobraznye-zadachki/xudozhnik-i-proxozhij.html

Page 13: cpp-2013 #20 Best practices

http://fomuvi.ru/zadachki/raznoobraznye-zadachki/xudozhnik-i-proxozhij.html

Page 14: cpp-2013 #20 Best practices

for (int i = 0; i < v.size(); i++){ cout << i << " " << v[i] << endl;}

for (int i = 0; v.size() - 1 >= i; ++i){ cout << i << " " << v[i] << endl;}

Page 15: cpp-2013 #20 Best practices

Side effects

Page 16: cpp-2013 #20 Best practices

Global mutable state

Page 17: cpp-2013 #20 Best practices

Coupling

Page 18: cpp-2013 #20 Best practices

Coupling (зв’язність)• Afferent– Скільки компонентів залежать від модуля– Показує наскільки модуль відповідальний

• Efferent– Від скількох компонентів залежить модуль– Показує наскільки модуль незалежний– Включає: наслідування, interface impl, типи

параметрів, типи змінних, exceptions,...• Ca and Ce є метриками стабільності

Page 19: cpp-2013 #20 Best practices

Instability I = Ce / (Ce + Ca)

• показує нестійкість до змін• 0 – стабільний модуль• 1 – нестабільний

Ce Ca

Page 20: cpp-2013 #20 Best practices

Cohesion (пов’язаність, зчеплення)• Показує наскільки сильні взаємозв’язки між

частинами одного модулю• Чи всі методи класу використовують всі

його поля• Низька пов’язаність:– Клас з багатьма статичними методами– “Несфокусований” клас

Page 21: cpp-2013 #20 Best practices

Cohesion

Кореляція: high complexity and low cohesion

Кореляція: complexity and number of defects

Page 22: cpp-2013 #20 Best practices

Low coupling + high cohesion сприяють легкому внесенню змін у ПЗ

Більшість шаблонів проектування є рецептами для зниження coupling та

підвищення cohesion

Page 23: cpp-2013 #20 Best practices

Dependencies

Page 24: cpp-2013 #20 Best practices

class Course{public: void Apply(shared_ptr<User> user) { auto application = new Application(/*...*/); //... auto email = new SmtpEmailSender(); email->send("New course application!", emailSettings.directorEmail()); }};

Page 25: cpp-2013 #20 Best practices

Course

SmtpEmailSender

High level module

Low level module

Depends on

Page 26: cpp-2013 #20 Best practices

class Course{private: IEmailSender* email;

public: Course(IEmailSender* email) : email(email) {}

void Apply(shared_ptr<User> user) { auto application = new Application(/*...*/); //... email->send("New course application!"); }};

Page 27: cpp-2013 #20 Best practices

Course

SmtpEmailSender

High level module

IEmailSender

Implements

Page 28: cpp-2013 #20 Best practices

Course

SmtpEmailSenderIEmailSender

Application

Page 29: cpp-2013 #20 Best practices

Course

SmtpEmailSender

High level module

IEmailSender

Dependency is inverted

Page 30: cpp-2013 #20 Best practices

Dependency inversion• High level modules should not depend on

low-level modules• Both should depend on abstractions• Abstractions should not depend on details• Details should depend on abstractions

Page 31: cpp-2013 #20 Best practices

Що отримуємо• Залежності вказуються явно, немає прихованих

залежностей• Класи самодокументовані• Класи більше не відповідають за створення об’єктів• Після створення клас гарантовано знаходиться у

робочому стані• Легко знаходити класи з багатьма параметрами в

конструкторі (і зменшувати їх відповідальності)• Легше знаходити методи, яким потрібні не всі

залежності класу

Lower coupling

Page 32: cpp-2013 #20 Best practices

class UsersImporter{public: void import() { auto importContext =

new ImportContext(currentUserName); // ... fileImporter->import(); // ... }};

Page 33: cpp-2013 #20 Best practices

? Залежить від ImportContext

? Тип повинен визначатись залежно від ImportContext

? Потрібно керувати часом життя FileImporter’а

void import(){ auto importContext = new ImportContext(currentUserName); // ... IFileImporter* fileImporter = new CsvFileImporter(importContext); fileImporter->import(); // ... delete fileImporter;}

Page 34: cpp-2013 #20 Best practices

Abstract Factory. Потреба:• Залежність залежить від параметра, який не

відомий клієнту на час його створення• if/else та switch блоки для вирішення, яку

залежність створити• Залежність потрібно до-ініціалізувати• Об’єкт повинен керувати часом життя

залежності

Page 35: cpp-2013 #20 Best practices

UsersImporter

CsvFileImporter

IFileImporter

Page 36: cpp-2013 #20 Best practices

UsersImporter

CsvFileImporter

IFileImporterFactory

IFileImporter

FileImporterFactory

Page 37: cpp-2013 #20 Best practices

Lowering coupling:simpler

but sometimes harder

Page 38: cpp-2013 #20 Best practices

Broken windows

http://en.wikipedia.org/wiki/Broken_windows_theory

Page 39: cpp-2013 #20 Best practices

Code Complete, Steve McConnellhttp://amzn.com/0735619670http://www.ozon.ru/context/detail/id/5508646/

Clean Code, Robert C. Martinhttp://amzn.com/0132350882http://www.ozon.ru/context/detail/id/6733562/