Upgrade to Pro — share decks privately, control downloads, hide ads and more …

АФТИ ООП 2013-2014. Лекция II/12

АФТИ ООП 2013-2014. Лекция II/12

Oleg Dashevskii

May 12, 2014
Tweet

More Decks by Oleg Dashevskii

Other Decks in Education

Transcript

  1. • «Простая логика, мало зависимостей, достаточная эффективность» • «Явный и

    простой. Читается как хорошо написанная проза. Выражает намерение» • «Может читаться и улучшаться другими людьми, не только автором. Есть тесты. Хорошие имена. Один результат достигается одним способом. Интерфейс минимален и предельно понятен» Что есть хороший код?
  2. • «Написан тем, кому было не всё равно. Не видно

    очевидного способа улучшить этот код — всё уже продумано» • «Не содержит дублирования. Выражает собой идеи, заложенные в дизайн системы. Минимизирует количество сущностей (классов, методов, функций, …)» • «Видишь то, что ожидал бы увидеть. Выглядит так, как будто язык специально был создан для решения этой задачи»
  3. ПОЛНЫЙ ПРОЦЕСС 1.Постановка задачи. 2.Семейство задач. 3.Архитектура. 4.Решение. 5.Тестирование. 6.Документирование.

    7.Ввод в эксплуатацию. 8.Новый взгляд на решение и на семейство решаемых задач. 9.Переделки согласно п.8.
  4. • «Некогда думать, давай быстро сделаем вот так и вот

    так, а потом всё сделаем начисто, когда будет время» • «Заработало? Скорее берись за следующую задачу, сроки поджимают!» • «Просто сделай, чтобы хоть как-то работало, а дальше уже не наши проблемы»
  5. ИМЕНА • Имя должно выражать намерение! int d; // elapsed

    time in days int elapsedTimeInDays;! int daysSinceCreation;! int daysSinceModification;! int fileAgeInDays; vs.
  6. vector<int *> getThem(const vector<int *> &theVec) {! vector<int *> vec1;!

    ! for (vector<int *>::const_iterator x = theVec.begin(); x != theVec.end(); ++x)! if ((*x)[0] == 4)! vec1.push_back(*x);! ! return vec1;! } vector<Cell> getFlaggedCells(const vector<Cell> &gameBoard) {! vector<Cell> flaggedCells;! ! for (vector<Cell>::const_iterator cell = gameBoard.begin();! cell != gameBoard.end(); ++cell)! if (cell->isFlagged())! flaggedCells.push_back(*cell);! ! return flaggedCells;! }!
  7. std::vector<Account> accountList; // сбивает с толку! ! int countVariable; //

    WTF, достаточно int count;! std::string nameString; // WTF, std::string name;! ! // Упрощаем имена:! // moneyAmount -> money! // customerInfo -> customer! // accountData -> account! // theMessage -> message
  8. • Имена классов: существительные. 
 Customer, WikiPage, Account, AddressParser. •

    Имена методов: глаголы.
 postPayment(), deletePage(), save(). • Не бойтесь переименовывать, если не удалось сразу придумать хорошее имя!
  9. ФУНКЦИИ И МЕТОДЫ • Короткие! (лучшая функция — несколько строк).

    • Делающие ровно одну вещь и при этом хорошо. Критерий: невозможно вынести часть кода в другую функцию. • Один уровень абстракции у всех операторов — необходимое условие для «ровно одной вещи».
  10. void generateReport(char *filename, Data *data)! {! std::ofstream ofs(filename);! ! if

    (!ofs)! return;! ! ofs << "REPORT" << std::endl;! ! for (int i = 0; i < data->sectionCount(); ++i)! generateReportSection(ofs, data->section(i));! ! ofs << "-----" << std::endl;! } Разные уровни абстракции!
  11. АРГУМЕНТЫ • Лучше всего — без аргументов. • Один или

    два аргумента — терпимо. • Три и более — лучше избегать всеми силами.
  12. • doSomething(bool) — ужас-ужас. Лучше уж разбить функцию на две.

    • Два аргумента легко перепутать:
 char *strstr(const char *s1,
 const char *s2); • Можно уменьшить количество аргументов, объединяя их в класс:
 Circle makeCircle(double x, double y,
 double radius);
 Circle makeCircle(Point center,
 double radius);!
  13. SIDE EFFECTS class UserValidator {! Cryptographer cryptographer;! ! public:! bool

    checkPassword(string userName, string password) {! User user = UserGateway.findByName(userName);! ! if (user) {! String codedPhrase = user.getPhraseEncodedByPassword();! String phrase = cryptographer.decrypt(codedPhrase, password);! ! if (phrase == "Valid Password")! Session.initialize();! ! return true;! }! }! return false;! }! };
  14. КЛАССЫ • Single Responsibility Principle • Open-Closed Principle • Liskov

    Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  15. ЧЕТЫРЕ ПРАВИЛА
 КЕНТА БЕКА • Код хорош, если: • он

    удовлетворяет тестам; • в нём отсутствует дублирование; • он выразителен; • он содержит минимальное количество классов и методов.
  16. УСТОЙЧИВЫЙ ПРОЦЕСС • Внесли изменения (в отдельной ветке системы контроля

    версий!). • Написали тест на верификацию нового поведения системы. • Добились рабочего состояния. • Прогнали все тесты и убедились, что ничего не поломали. • Применили к коду правила хорошего кода. • Прогнали тесты… • GO TO 10
  17. РЕФАКТОРИНГ • Переименование переменных / классов / методов. • Перенос

    методов между классами (по иерархии и так). • Выделение какого-то функционала в отдельный класс (или наоборот). • Разделение функций на более мелкие (или наоборот). • Применение паттернов проектирования для большей выразительности. • …