Изобретение велосипеда (Reinventing the wheel) — КиберПедия 

Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Изобретение велосипеда (Reinventing the wheel)



Суть данного антипаттерна заключается в разработке собственного решения задачи, для которой существует известное решение. Например, разработка классов-контейнеров, которые могут быть найдены в сторонних библиотеках.

Причиной разработки собственного решения является нежелание программиста изучать существующие аналоги и внедрять их в программный код. Как ни странно, нехватка времени также может быть причиной данного антипаттерна. Разработчик, не желая тратить время на поиск, который может закончиться неудачей, сразу приступает к самостоятельному решению задачи. Часто собственное решение оказывается хуже, чем существующее.

Следствием изобретения велосипеда является ненужная трата времени на неоптимальное решение, а также высокая вероятность внесения ошибок в программный код.

Программист в ходе своей работы должен уметь находить баланс между поиском готовых решений и изобретением новых. Изобретение своего решения, а не внедрение или адаптация существующего, сопряжено со значительными трудозатратами, поэтому должно быть обосновано. Кроме этого, внедряя свое решение, программист берет не себя ответственность за его сопровождение и развитие, в то время как сторонние решения могут развиваться силами сообщества разработчиков или конкретной организации.

 

Программирование перебором (Programming by permutation)

Программирование перебором характерно для программистов, которые не в полной мере понимают суть решаемой задачи. Вследствие такого недопонимания программист не может сформулировать четкое решение и приступает к его подбору.

Явным признаком антипаттерна является увеличение или уменьшение числовых констант на единицу в надежде, что программа заработает правильно. Например, при реализации некоторого алгоритма над коллекцией элементов программист может пытаться подгонять значения индекса. Данный антипаттерн проявляется также в виде перемены порядка вызова функций без понимания действий, которые они выполняют.

Результатом такого метода программирования может стать код, который работает корректно для некоторого набора входных параметров, но в дальнейшем может привести к ошибкам. Главная проблема заключается в том, что даже после получения работоспособного кода программист не сможет четко сформулировать, как этот код работает.

Для исключения данного антипаттерна необходимо развивать культуру разработки и повышать уровень компетенции, изучая предметную область, алгоритмы и технологии.



 

Выводы

Рассмотренные в данной главе антипаттерны должны быть знакомы разработчикам. Подобно паттернам проектирования, позволяющим создавать гибкие решения, поддающиеся масштабированию и модернизации, знание антипаттернов позволяет избежать ошибок, которые с увеличением объема программного кода будут оказывать все более сильное негативное действие, препятствуя дальнейшей разработке программы.

Основной причиной возникновения антипаттернов в разработке программного обеспечения является нехватка времени, недостаток опыта и знаний. Эффект от антипаттернов особенно сильно заметен на крупных программных продуктах с большим количеством разработчиков и длительным жизненным циклом, поэтому лучшим способом борьбы с ними является грамотное планирование и проектирование программы.

8. СТАНДАРТ C++11

 

Стандарт языка программирования ISO/IEC 14882:2011, неформально именуемый C++11, пришел на смену более раннему стандарту 2003 года ISO/IEC 14882:2003. В настоящее время уже утвержден стандарт С++14 − ISO/IEC 14882:2014, стандарт С++17 находится в разработке.

В тексте данной книги мы уже не раз использовали возможности, появившиеся в C++11. В данной главе мы рассмотрим их более глубоко, а также затронем некоторые темы, которые ранее не встречались.

 

Выведение типов

Механизм автоматического выведения типов позволяет избавить программиста от необходимости самостоятельно указывать необходимый тип переменной при объявлении. В С++11 вместо типа можно указать ключевое слов auto, и компилятор самостоятельно выведет нужный тип.

 

// Пример 8.1 - автоматический вывод типов при инициализации переменных

int i = 1;

float f = 1.1;

auto i2 = 2;

auto f2 = 2.2;

std::cout << "i: " << i << ", " << "i2: " << i2 << std::endl;

std::cout << "f: " << f << ", " << "f2: " << f2 << std::endl;

 

Результат работы программы следующий:



i: 1, i2: 2

f: 1.1, f2: 2.2

Тип данных может быть определен исходя из типа возвращаемого значения функции.

 

// Пример 8.2 - автоматический вывод типов при вызове функции

const std::string& getString()

{

static std::string s = "Hello";

return s;

}

auto s = getString();

std::cout << s << std::endl;

Результат работы программы следующий:

Hello

 

При работе с контейнерами стандартной библиотеки ключевое слова auto может быть использовано для сокращения записи при указании типа итератора.

 

// Пример 8.3 - автоматический вывод типов при работе с итераторами

std::map<std::string, int> numbers = {

{"One", 1}, {"Two", 2}, {"Three", 3}

};

 

std::map<std::string, int>::const_iterator it = numbers.begin();

for(; it != numbers.end(); ++it)

std::cout << it->first << " , " << it->second << std::endl;

 

auto aIt = numbers.begin();

for(; aIt != numbers.end(); ++aIt)

std::cout << aIt->first << " , " << aIt->second << std::endl;

 

decltype(aIt) aIt2 = numbers.begin();

for(; aIt2 != numbers.end(); ++aIt2)

std::cout << aIt2->first << " , " << aIt2->second << std::endl;

 

Результат работы программы следующий:

One , 1

Three , 3

Two , 2

One , 1

Three , 3

Two , 2

One , 1

Three , 3

Two , 2

 

В первом случае тип данных указан явно, во втором случае был использован автоматический вывод типов, в третьем случае было использовано ключевое слово decltype, позволяющее определить тип данных переменной. Как легко убедиться, вывод программы для всех трех случаев идентичный.

Ключевое слово decltype используется для определения типа данных переменной. Оно необходимо, так как автоматически выведенный тип известен только компилятору, и для объявления новой переменной такого же типа используется конструкция вида decltype(other_var) new_var.

 

Списки инициализации

В стандарте С++11 вводится специальный класс для работы со списками инициализации, т.е. конструкциями вида {1,2,3,4,5} − std::initializer_list. Данный класс является шаблонным, экземпляры данного класса создаются компилятором статически. Список инициализации является константным и не может быть изменен во время работы программы.

Контейнерам стандартной библиотеки могут быть присвоены изначальные значения при помощи списка инициализации. Далее приведены два примера кода для контейнера std::vector и std::map.

 

// Пример 8.4 - начальное состояние контейнера std::vector, задаваемое

// с помощью списка инициализации.

std::cout << "Vector\n";

std::vector<int> vec = {1,2,3,4,5,6,7,8,9,10};

for(auto it = vec.begin(); it != vec.end(); ++it)

std::cout << *it << ' ';

std::cout << std::endl;

 

Результат работы программы следующий:

Vector

1 2 3 4 5 6 7 8 9 10

 

// Пример 8.5 - начальное состояние контейнера std::map, задаваемое

// с помощью списка инициализации.

std::cout << "Map\n";

std::map<std::string, std::string> m = {

{"Hello", "World"},{"Moscow","Russia"},{"London","GB"}};

for(std::map<std::string, std::string>::iterator it = m.begin(); it != m.end(); ++it)

std::cout << it->first << ", " << it->second << std::endl;

 

Результат работы программы следующий:

Map

Hello, World

London, GB

Moscow, Russia

 

Класс может содержать конструктор с параметром − списком инициализации, создание объекта такого класса будет схоже с созданием статического массива. Список инициализации может быть использован и для передачи параметров в функцию. В следующем фрагменте кода показаны обе эти возможности.

 

// Пример 8.6 - список инициализации в качестве параметра конструктора

class IListConstructed

{

int x, y, z;

public:

IListConstructed(std::initializer_list<int> il) {

x = *(il.begin() + 0);

y = *(il.begin() + 1);

z = *(il.begin() + 2);

}

void print() {

std::cout << "IListConstructed: " << x << y << z << std::endl;

}

void set(std::initializer_list<int> il) {

x = *(il.begin() + 0);

y = *(il.begin() + 1);

z = *(il.begin() + 2);

}

};

IListConstructed ic = {1,2,3};

ic.print();

ic.set({2,3,4});

ic.print();

 

Результат работы программы следующий:

IListConstructed: 123

IListConstructed: 234

 

В следующем фрагменте кода показан пример использования списка инициализации для передачи параметров в функцию. Для доступа к элементам списка инициализации используется итератор по аналогии с другими контейнерами стандартной библиотеки.

 

// Пример 8.7 - список инициализации в качестве параметра функции

int getMax(std::initializer_list<int> iList)

{

if(iList.size() == 0){

std::cout << "Empty initializer list" << std::endl;

return 0;

}

 

int value = *iList.begin();

for( std::initializer_list<int>::iterator it = iList.begin();

it != iList.end();

++it)

value = value > *it ? value : *it;

return value;

}

std::cout << getMax({3,2,1}) << std::endl;

std::cout << getMax({1,2,3}) << std::endl;

std::cout << getMax({}) << std::endl;

 

Результат работы программы следующий:

Empty initializer list

 






Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...





© cyberpedia.su 2017 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав

0.012 с.