пятница, 30 апреля 2010 г.

Стив Джобс рассказал, почему Apple "не пускает" Flash на свои мобильные устройства

Материал взят из http://hitech.newsru.com/article/30apr2010/applewhynoflash

Глава Apple Стив Джобс разместил на официальном сайте компании открытое письмо Thoughts on Flash ("Размышления о Flash"). В нем он, как сообщает Ferra.ru постарался изложить свое видение причин, по которым Apple не разрешает и не разрешит использование технологии Flash на своих мобильных устройствах.

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

Аргумент Adobe о том, что благодаря отсутствию поддержки Flash пользователи iPhone и iPad лишаются полноценного доступа к веб-ресурсам, глава Apple называет устаревшим. Сайты YouTube, CBS, Netflix, Facebook и многие другие поддерживают работу с мобильными устройствами Apple.

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

Стив Джобс напоминает, что его специалисты в течение нескольких лет просили Adobe показать хорошо работающую технологию Flash на любом мобильном устройстве. Однако этого так и не случилось.

Что касается флеш-игр, Стив Джобс указывает, что им есть неплохая альтернатива в виде программ из App Store. Сейчас в этом онлайн-магазине присутствует более 50 000 игр и развлекательных приложений, причем, многие из них бесплатны.

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

Стив Джобс также отмечает, что технология Flash была разработана для ПК и компьютерной мыши, а не для сенсорных экранов, в то время как у Apple имеется фирменный multi-touch интерфейс, не требующий ничего, кроме пальцев.

Поэтому большинство сайтов с применением Flash все равно придется переписывать под устройства с сенсорным экраном. В Apple решили сразу делать это с применением современных технологий - например, HTML5, CSS и JavaScript.

Работа с локальным SVN-репозитарием

Mac OS предоставляет возможность сохранять версии своих исходников и вообще любых проектов - в системе уже установлен готовый SVN-клиент.

Кроме того, SVN-клиент также имеется в Xcode, но лично я предпочитаю работать через Терминал (командную строку).

1. Сначала нужно создать локальный SVN-репозитарий

Допустим, вы хотите создать репозитарий в виде папки SVN_R, которая будет расположена в папке /Volumes/Data/MyRepositories/ (то есть в папке MyRepositories, которая будет лежать в корне диска Data).

Для этого войдите в папку
MyRepositories (через Терминал):

cd /Volumes/Data/
MyRepositories

После этого создайте репозитарий такой командой (папку SVN_R не создавайте)

svnadmin create SVN_R

Теперь у вас создана папка, содержащая в себе SVN-репозитарий пока без каких-либо сохранённых там проектов.

Кроме того, вы можете создавать внутри репозитария папки под разные проекты с помощью команды (например, для создания папки
Project1Repository)

svn mkdir file:///Volumes/Data/SVN_R/Project1Repository

2. Теперь нужно импортировать имеющийся проект в созданный репозитарий

Теперь вы можете импортировать в этот созданный репозитарий тот проект (папку
MyProject1, содержащую проект) с помощью команды (если хотите импортировать именно в корень репозитария, далее мы будем считать, что так и сделали)

svn import /AllProjects/MyProject1 file:///Volumes/Data/SVN_R
-m 'Импортировал свой проект 1'

3. Теперь нужно выкачать (chekout) из репозитария этот проект в новую рабочую папку (ту самую папку, которой суждено будет находиться под версионным контролем всю свою жизнь)

svn checkout file:///Volumes/Data/SVN_R ~/MyVersionedProjects

Символ ~ (тильда) означает вашу домашнюю папку (обычно имеющее название совпадающее с именем пользователя в Mac OS или Unix/Linux). То есть из репозитария будет выкачан проект именно в папку MyVersionedProjects, но после этого действия проект будет виден как папка
MyProject1 внутри папки MyVersionedProjects (очень важно, чтобы вы не создавали сами папку MyProject1 заранее в папке MyVersionedProjects, иначе в ней появятся одни лишь служебные файлы, а не сам проект). Кроме проекта вы увидите некоторые служебные файлы и папки, в названиях которых может содержаться точка и слово svn. Ни в коем случае не удаляйте их, они нужны для обеспечения версионного контроля.

Теперь работайте с проектом только в этой рабочей папке (куда только что выкачали проект из репозитария).

4. Сохранение очередных версий (commit)

Когда вы захотите сохранить очередную версию вашего проекта, то зайдите в Терминале в РАБОЧУЮ папку проекта и закоммитьте проект

cd
~/MyVersionedProjects
svn commit -m 'Очередная версия (исправил косяк с загрузкой файлов, остался ещё косяк в GUI)'

5. Как посмотреть комментарии к прежним версиям

Для этого с помощью команды cd зайдите в терминале в рабочую папку проекта и выполните команду (для случая, если вы хотите посмотреть комментарии от 1 до 3 версии)

svn log -r 1:3

Вот что вы примерно увидите после выполнения этой команды:
------------------------------------------------------------------------
r1 | Murat | 2010-04-28 13:58:34 +0700 (ср, 28 апр 2010) | 1 line

Create temporary repositary until purchase Teamprise Explorer
------------------------------------------------------------------------
r2 | Murat | 2010-04-28 21:00:03 +0700 (ср, 28 апр 2010) | 1 line

Добавил ОПИСАНИЕ.txt - буду описывать, что я понял из исходников (которые не мои)
------------------------------------------------------------------------
r3 | Murat | 2010-04-29 13:18:54 +0700 (чт, 29 апр 2010) | 1 line

Добавил скрипты для автоматизации сборки, копирования заголовков, очистки проектов
------------------------------------------------------------------------

Таким образом, можно принять решение о том, к какой именно версии вы хотите откатиться.


6. Как откатиться к одной из предыдущих версий

Наиболее удобно восстанавливать одну из предыдущих версий не в рабочую, а в отдельную папку (но это лишь мой опыт, так что решайте сами на этот счёт).

Создайте отдельную папку (например на рабочем столе папку OLD_VERSION_2). Выполните такую команду, если хотите откатиться ко 2-й версии:

svn checkout
file:///Volumes/Data/SVN_R ~/Desktop/OLD_VERSION_2 -r 2

После выполнения этой команды кроме списка из всех восстановленных файлов внизу вы увидите сообщение
Checked out revision 2.

Теперь в папке OLD_VERSION_2 находится вся 2-я версия, полученная из репозитария.

7. Сравнение версий файлов

SVN предоставляет возможность просмотра в Терминале (в командной строке) различий между версиями файлов (для этого введите команду svn help и поищите в интернете справку), но я предпочитаю для этого использовать бесплатную программу kdiff3 (домашняя страница этой программы -
http://kdiff3.sourceforge.net/). Эта программа позволяет увидеть различия в текстовых исходниках просто из разных папок (выделяя различия в тексте цветом).

Но SVN позволяет увидеть различия между указанными версиями указанных файлов.
Для того, чтобы увидеть чем отличается 3-я версия
файла ОПИСАНИЕ.txt от 2-й версии в текущей папке, введите команду

svn diff -r 2:3 ОПИСАНИЕ.txt

8. Получение справки не отходя от кассы

Общая справка
svn help

Справка по выбранной команде (например, по команде diff)
svn help diff

Как в Mac OS снять блокировку/защиту из всех файлов выбранной папки

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

Для этого можете запустить Terminal (командную строку), зайти в папку проекта (используя команду cd).

После этого вводите команды:

chflags -R nouchg *
chflags -R nouchg */*
chflags -R nouchg */*/*
chflags -R nouchg */*/*/*
chflags -R nouchg */*/*/*/*
и так далее

Делайте так до тех пор, пока Terminal вам не сообщит, что таких файлов или папок больше не обнаружено (то есть когда глубина вложенных директорий достигнет самых последних закоулков). Это будет похоже вот на что:
chflags: */*/*/*/*/*/*/*/*: No such file or directory

ЕСЛИ КТО-ТО ЗНАЕТ, КАК МОЖНО ЗАМЕНИТЬ ЭТО ПРОСТЫМ SHELL-СКРИПТОМ, ПОЖАЛУЙСТА ПОДЕЛИТЕСЬ ОПЫТОМ.

Как получить пути к наиболее часто используемым папкам в iPhone-приложении

Вот как я обычно получаю все необходимые мне пути:

// 1. Путь к папке Documents:
NSString *nsDocsDir =
[NSHomeDirectory() stringByAppendingPathComponent:
@"Documents"];


// 2. Путь к кэш-папке (там хорошо что-либо временное сохранять, такое, что не жалко будет пользователю потерять):
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *nsCachesDir = [paths objectAtIndex:0];

// 3. Путь к папке ресурсов:
NSString* resourcesDir = [[NSBundle mainBundle] resourcePath];

// И ещё пара полезных функций:
NSString* homeDir = NSHomeDirectory(); // вероятно, это корневая папка приложения
NSString* tempDir = NSTemporaryDirectory(); // возвращает полный путь к папке для временных файлов

Внимание: автор не претендует на полноту изложения! Смотрите документацию от Apple.

Как автоматически копировать нужные заголовки в нужное место при сборке Xcode-проекта

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

Предыстория:

Мне не хочется, чтобы разные проекты зависели от их относительного расположения на диске. При этом я хочу, чтобы заголовки всех моих библиотек (как и сами бинарники) всегда лежали в одном и том же месте, независимо от того, где находятся сами проекты библиотек.

Что я хочу автоматизировать:

В моей ситуации нужно копировать только некоторые заголовочные файлы в определённое место (например, в папку /MyLibs/include/QuartzDrawingLib/).

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

Как это можно сделать?

1-й способ (через добавление скрипта):

Посмотрите на дерево Xcode-проекта. Там есть ниже всех исходников Targets (с иконкой, напоминающей красную мишень). Выберите в Targets вашу цель (как правило с названием вашего проекта), нажмите на неё правой кнопкой мыши и выберите из контестного меню Add - > New Build Phase - > New Run Script Build Phase.

После этого появится окно, в которое нужно ввести текст скрипта. Туда вообще можно вводить любые команды, которые вы могли бы вручную набрать в консоли.

Я ввёл примерно следующее:

destDir=/MyLibs/include/QuartzDrawingLib/
if [ -d "$destDir" ]
then
echo "Directory "$destDir" is found"
else
echo "Directory "$destDir" will be created"
mkdir "$destDir"
if [ -d "$destDir" ]
then
echo "Directory "$destDir" is created"
else
echo "Directory "$destDir" is not created!"
echo "Exit script..."
exit 1
fi
fi

echo Copying headers...

cp Classes/SomeClass1.h $destDir
cp Classes/SomeClass2.h $destDir
cp Classes/SomeClass3.h $destDir
cp Classes/SomeClass4.h $destDir
cp Classes/SomeClass5.h $destDir

и так далее (из папки Classes в текущей директории копируются все ТОЛЬКО НУЖНЫЕ МНЕ заголовки в корень системного диска в папку /MyLibs/include/QuartzDrawingLib/

Теперь не нужно это делать каждый раз вручную.

Всё тоже самое можно сделать ВНЕ ПРОЕКТА как отдельный исполняемый скрипт (в виде обычного текстового файла), только перед написанием всех команд не забудьте сверху написать #!/bin/bash
Кроме того, после написания скрипта (т.е. текстового файла ВНЕ ПРОЕКТА) нужно данный текстовый файл сделать исполняемым - для этого выполните в консоли команду:
chmod +x NameOfScriptFile

2-й способ (который значительно проще, но менее надёжный, так как не гарантирует обновление имеющихся копий заголовков, т.е. их приходится удалять и снова нажимать кнопку Build):

Выберите в Targets вашу цель (как правило с названием вашего проекта), нажмите на неё правой кнопкой мыши и выберите из контестного меню Add - > New Build Phase - > New Copy Files Build Phase (после появления новой иконки добавленной фазы, в настройках этой фазы можно указать абсолютный путь куда копировать те файлы, которые вы будете добавлять в эту фазу в дереве проекта).

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

Чем заменить функцию stricmp в iPhone-проекте

Я пошарился в Гугле и нашёл интересный ответ на этот вопрос:

Смотрите документацию (введите man strcasecmp в командной строке - возможны какие-то различия в возвращаемых int-значениях).

Легендарный редактор vi

vi

Материал из Википедии — свободной энциклопедии

vi (visual) — серия текстовых редакторов операционных систем семейства UNIX.

Содержание

//

История

Первая версия была написана Биллом Джоем (англ.) в 1976 году.

В то время наиболее распространённым был редактор ed. Поскольку он был довольно сложным для «простого смертного», George Coulouris разработал редактор em (editor for mortals — редактор для смертных). Билл Джой модифицировал редактор em и назвал его en, а позднее — он получил название ex, на котором и основан vi[1].

Интерфейс

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

В режиме вставки клавиатура используется для набора текста. Для выхода в командный режим используется клавиша Esc или комбинация Ctrl + c .

В командном режиме алфавитные клавиши соответствуют командам перемещения и изменения текста. Так, команды h, j, k, l перемещают курсор на одну позицию влево, вниз, вверх, вправо соответственно, команда x удаляет один символ и т. д. Это позволяет работать без необходимости использования дополнительной клавиатуры и клавиш-модификаторов, таких, как Ctrl , Alt и т. д. Более сложные операции редактирования получаются комбинацией простых, например, 2dw удаляет два слова. Для полнотекстовых операций имеется возможность задавать команды ex в подобии командной строки, например, :1,.s/wiki/[[wiki]]/g заключит все вхождения последовательности символов wiki от начала текста до текущей позиции в двойные квадратные скобки.

Часто используемые команды

  • /str — Поиск строки str вперед. str может быть регулярным выражением
  • ?/str — Поиск строки str назад
  • n — Повторить поиск в том же направлении
  • N — Повторить поиск в обратном направлении
  • :[range]s/old/new/[g] — Заменить old на new в указанном диапазоне строк range. new и old могут быть регулярными выражениями, а range задается аналогично диапазону строк в редакторе ed. Суффикс g означает заменить во всем файле.
  • :e! — перезагрузить текущий файл
  • :33 — перепрыгнуть на 33ю строку текстового файла
  • i — перейти в режим редактирования
  • a — перейти в режим редактирования после текущего символа
  • u — отменить последнее действие
  • x — удалить символ под курсором
  • dd — удалить всю строку
  • /qso — найти слово qso в тексте после курсора
  • :w — сохранить файл на диске
  • :wq — выход с сохранением файла
  • :q — выход
  • :q! — выход без сохранения файла


Чтобы получить подробную помощь по редактору vi, выполните команду man vi в Unix shell (q — выход из справки).

Использование регулярных выражений

  • /^$/ — пустая строка, т.е. только конец строки
  • /./ — непустая строка, по крайней мере один символ
  • /^/ — все строки
  • /thing/ — thing где-либо в строке
  • /^thing/ — thing в начале строки
  • /thing$/ — thing в конце строки
  • /^thing$/ — строка, состоящая лишь из thing
  • /thing.$/ — thing плюс любой символ в конце строки
  • /\/thing\// — /thing/ где-либо в строке
  • /[tT]hing/ — thing или Thing где-либо в строке
  • /thing[0-9]/ — thing, за которой идет одна цифра
  • /thing[^0-9]/ — thing, за которой идет не цифра
  • /thing1.*thing2/ — thing1, затем любая строка, затем thing2
  • /^thing1.*thing2$/ — thing1 в начале и thing2 в конце

Чтобы манипулировать не только целыми фрагментами, выбираемыми регулярными выражениями, но и их частями, используются помеченные регулярные выражения: если конструкция \(...\) появляется в регулярном выражении, то часть соответствующего ей фрагмента доступна как \1. Допускается использование до девяти помеченных выражений, на которые ссылаются \1, \2 и т.д.

Вот ряд примеров использования помеченных регулярных выражений:

  • s/\(...\)\(.*\)/\2\1/ — Поместить 3 первых символа в конец строки
  • /\(..*\)\1/ — Найти строки, содержащие повторяющиеся смежные цепочки символов
  • s/^\(..*\)\.\(..*\)/\1.\\2/ — Перенести остаток строки после первой точки на следующую строку

Другие редакторы

Спор между сторонниками vi и emacs является классическим примером «религиозных войн».

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

Клоны vi

Ссылки

Как выяснить причину EXC_BAD_ACCESS в Xcode

Нашёл интересную статью (на английском) на http://www.codza.com/how-to-debug-exc_bad_access-on-iphone (там это приводится с рисунками и комментариями читателей).

НАЧАЛО ЦИТАТЫ.

EXC_BAD_ACCESS. Debugging this one is on par with figuring out why the wife says “not tonight, honey.” And they are equally unfortunate situations.

Let’s see what we can do about EXC_BAD_ACCESS.

EXC_BAD_ACCESS happens when a message is sent to an object that has already been released. By the time the error is caught, the call stack is usually gone especially if dealing with multiple threads.

How nice would it be to keep a dummy around after the object is released that could stop execution, tell us what message was sent and show us the call stack… well, there’s a way to do just that.

If you set the NSZombieEnabled environment variable, the Objective C runtime will leave a dummy object behind for every deallocated object. When the zombie object is called, execution stops and you can see the message that was sent to the object and the call stack that tells you where the message came from (it doesn’t tell you where you over released the object, but knowing where the object is called from should get you pretty close to the problem.)

To set this variable, go to the info panel of the executable in xcode, and create a new environment variable in the arguments tab by clicking the plus sign in the lower left corner of the window. Name the variable NSZombieEnabled, type YES for the value and make sure that the checkbox is selected.
set NSZombieEnabled variable

set NSZombieEnabled variable

Go ahead and run your program now (in debug mode, because you need the stack information.) When the over released object is accessed, you get an error message similar to this (xcode debug view):

2009-03-30 02:30:36.172 ninjaJumper[3997:20b] *** -[GameLayer retain]: message sent
to deallocated instance 0x59bf670

This shows the class of the object (GameLayer) and the message sent (retain).

Let’s take a look at the stack now:
call stack

call stack

The methods printed in bold are in your code, the others are in some other API. Here you can see that the object was accessed from [Director touchesBegan:withEvent], where an array was copied (most likely the over released object was in the array.)

This information should get you pretty close to the problem.

Once the problem is fixed, make sure that the NSZombieEnabled variable is disabled. You don’t need to delete it, but make sure that the checkbox is unchecked:
NSZombie disabled

NSZombie disabled

Now about the wife. Good luck there. Try a box of chocolate or load the dishwasher for a couple days.

КОНЕЦ ЦИТАТЫ.

К СОЖАЛЕНИЮ, ДАННЫЙ СОВЕТ ПОЗВОЛЯЕТ ОТСЛЕЖИВАТЬ ИМЕНА Objective C КЛАССОВ. Я ТОЛЬКО ЧТО СДЕЛАЛ ТЕСТОВОЕ ПРИЛОЖЕНИЕ, В КОТОРОМ ПОЛЕЗНЫЕ ОТЛАДОЧНЫЕ СООБЩЕНИЯ ВЫВОДЯТСЯ В КОНСОЛЬ ТОЛЬКО КАСАЕМО Objective C КЛАССОВ:


TestClass *testObj = [[TestClass alloc] init];
[testObj release]; // уничтожили объект перед попыткой использования
[testObj printMsg];

В этом случае в консоль будет выводиться информация
2010-04-28 13:02:08.030 ZombieTest[1353:207] *** -[TestClass printMsg]: message sent to deallocated instance 0x3924880)


В случае же с C++ классом:

TestCppClass *tcpp = new TestCppClass();
delete tcpp;
tcpp = 0;
tcpp- >PrintMsg(); // удивительно, но это работает (на экран выводится тестовое сообщение, так как вероятно функция-член класса способна работать и без создания объекта - ЭТО ЧТО, ОЧЕРЕДНОЙ БАГ Xcode?)
delete tcpp; // тем не менее здесь код спотыкается, так как пытаемся уничтожить объект повторно

в консоль выводится то же самое что и без применения совета из приведённой статьи):
2010-04-28 13:04:45.242 ZombieTest[1476:207] TestClass --- printMsg
ZombieTest(1476,0xa0a7b4e0) malloc: *** error for object 0x3917160: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Что делать, если в Xcode-отладчике невозможно переключиться на другой поток

Лично у меня получается переключиться между потоками, как только я нажму Pause-кнопку (т.е. остановлю приложение). По крайней мере можно увидеть, что происходило в тот момент в разных потоках.

Нашёл некоторое объяснение на http://www.cocoabuilder.com/archive/xcode/248374-debug-problem-in-multithreaded-environment-in-xcode.html

Там такой ответ и совет, надеюсь, программисты умеют читать по-английски:

Sometimes this happens because of the same reason that the backtrace
stack gets bumped off the top of the screen. This is a known problem
that we are investigating. Try toggling the debugger layout (using
the Toggle Debugger Layout command) or deleting the .mode1 file
in your Project's bundle.

вторник, 27 апреля 2010 г.

Как изменить размер стека потока средствами pthread-функций

pthread_attr_t threadAttr;
pthread_t tid_;

// initialize the thread attribute
assert(!pthread_attr_init(&threadAttr));

// Set the stack size of the thread (for example 2 Mb)
assert(!pthread_attr_setstacksize(&threadAttr, 1024*1024*2));

size_t stackSize;

// Проверим, точно ли у нас размер стека 2 Mb
assert(!pthread_attr_getstacksize(&threadAttr, &stackSize));
printf("The stack size is %d. ***\n", (int) stackSize);

// Создаём поток с заданным размером стека
assert(!pthread_create(&tid_, &threadAttr, thread_func, function_));

// подчистим за собой
assert(!pthread_attr_destroy(&threadAttr));

Интересные материалы для C++ программистов в блоге "Алёна C++"

Очень интересные материалы найдут для себя C++ программисты в блоге Алёны Сагалаевой:
http://alenacpp.blogspot.com/

Например, я только что нашёл интересный пример о константных ссылках (в свою очередь Алёна нашла этот пример в блоге знаменитого Герба Саттера http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry):

ЦИТИРУЮ ИЗ БЛОГА АЛЁНЫ (http://alenacpp.blogspot.com/2008/01/const.html):

Возможно, самый важный const

Герб Саттер у себя в блоге рассказывает про интересный случай с использованием const.

Краткий пересказ для ленивых.


string f() { return "abc"; }

void g() {
const string& s = f();
cout < < s < < endl; // можно ли использовать временный объект?
}


Код несколько напрягает. Создается ссылка на временный объект. Но тем не менее, с кодом все в порядке. Почему так? Потому что в С++ явно специфицировано, что если привязать временный объект к ссылке на const в стеке, то жизнь временного объекта будет продлена. Теперь он будет жить столько, сколько живет константная ссылка на него. В приведенном примере все валидно, время жизни s заканчивается с закрывающей фигурной скобкой.

Это все относится только к объектам в стеке. На члены класса это не действует.

С++ это специфицирует, а как оно в реальности, работает? Герб проверил в нескольких компиляторах, нормально, практически во всех работает.

Легким движением руки убираем const...

string f() { return "abc"; }

void g() {
string& s = f(); // все еще нормально?
cout < < s < < endl;
}
И получаем невалидный код, наличие const'а тут важно. Правильный компилятор выдаст ошибку на этапе компиляции.

И есть еще момент с вызовом деструктора.
Derived factory(); // construct a Derived object

void g() {
const Base& b = factory(); // здесь вызов Derived::Derived
// … используем b …
} // здесь вызывается Derived::~Derived напрямую
//-- а не Base::~Base + virtual dispatch!
Ссылки по теме:
Использование const. Часть 1.
Использование const. Часть 2.

КОНЕЦ ЦИТАТЫ

Принципы Agile Software Development

Что такое Принципы Дизайна Программного Обеспечения?

Принципы дизайна ПО представляют набор правил, который помогает избежать плохого дизайна. Принципы дизайна объединены Робертом Мартином, кто собрал их в "Agile Software Development: Principles, Patterns, and Practices" (т.е. "Быстрая разработка ПО: Принципы, Паттерны и Практика"). Согласно Роберту Мартину есть 3 важные характеристики плохого дизайна, которые нужно избегать:
Жёсткость - это когда трудно что-либо изменять в коде, так как каждое изменение оказывает воздействие на слишком много других частей системы.
Хрупкость - когда вы делаете изменение, и это приводит к неожиданной поломке других частей системы.
Непереносимость - код трудно повторно использовать в другом приложении, потому что этот код невозможно освободить от имеющегося приложения.

Принцип Открытости-Закрытости (Open Close Principle или OCP)


Программные сущности такие как классы, модули и функции должны быть открыты для расширения, но закрыты для изменений.
OPC является основополагающим принципом. Вы можете обсуждать его, когда пишете ваши классы, чтобы быть уверенными в том, что когда вам будет нужно расширить поведение, вы не должны будете изменять класс, но можете расширять его. Подобный же принцип применим для модулей, пакетов и библиотек. Если у вас есть библиотека, состоящая из множества классов, то есть много причин для того, чтобы вы предпочитали расширение вместо изменения кода, который уже написан (ради обратной совместимости, возвращение к предыдущему тестированию и т.п.). Это причина, по которой мы должны быть уверены, что наши модули следуют Принципу Открытости-Закрытости. По отношению к классам Принцип Открытости-Закрытости может быть гарантированно полезен засчёт использования Абстрактных Классов и конкретных классов для реализации их поведения. Это будет вынуждать иметь Конкретные Классы в качестве расширяющих Абстрактные Классы вместо их изменения. Некоторые частные случаи этого принципа есть Шаблонный Паттерн и Стратегический Паттерн (Template Pattern and Strategy Pattern).

Принцип Инверсии Зависимостей (Dependency Inversion Principle)


Высокоуровеневые модули должны не зависеть от низкоуровневых модулей. Оба должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Принцип Инверсии Зависимостей (Dependency Inversion Principle) формулирует, что мы должны отделять высокоуровневые модули от низкоуровневых модулей, вставляя слой абстракции между высокоуровневыми классами и низкоуровневыми классами. Более того этот принцип инвертирует зависимости: вместо написания наших абстракций, основанных на деталях мы должны писать детали, основанные на абстракциях.

Инверсия Зависимостей или Инверсия Контроля являются более понимаемыми терминами если ссылаться на способ, которым эти зависимости реализованы. Классическим способом в ситуации, когда программный модуль (класс, фреймворк, ...) нуждается в каком-нибудь другом модуле, он инициализует и держит прямую ссылку на этот другой модуль. Это приводит к тому, что 2 модуля становятся туго спаренными. Для их разъединения первый модуль будет обеспечиваться хуком, т.е. крючком (свойство, параметр, ...) и внешний модуль контролирующий зависимости будет добавлять ссылку на второй модуль. Засчёт применения Инверсии Зависимостей модули могут быть легко изменяемы другими модулями всего лишь засчёт изменения модуля зависимостей. Фабрики и Абстрактные Фабрики могут быть использованы в качестве фреймворков зависимостей, однако они являются специализированными фрейморками для того, что известно под названием Инверсия Контрольного Контейнера (Inversion of Control Container).

Принцип Отделения Интерфейса (Interface Segregation Principle)


Клиенты не должны принуждаться к зависимости от интерфейсов, которые они не используют.

Этот принцип учит нас заботиться о том, как мы пишем наши интерфейсы. Когда мы пишем интерфейсы, мы должны позаботиться о добавлении только тех методов, которые там должны быть. Если мы добавляем методы, которые не должны быть там, тогда классы реализующие интерфейс будут должны реализовывать эти лишние методы так же как и остальные методы. Например, если мы создаём интрфейс, называемый Worker (Рабочий) и добавляем метод lunch break (обеденный перерыв), тогда все workers (рабочие) будут должны иметь реализацию этого лишнего метода. А что если рабочий оказался роботом?

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


Принцип Единственной Ответственности (Single Responsibility Principle)


Класс должен иметь только одну причину для изменения.

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

Принцип Единственной Ответственности был введён Tom DeMarco в его книге "Structured Analysis and Systems Specification, 1979". Роберт Мартин реинтерпретировал эту концепцию и определил, что ответственность является причиной для изменения.


Принцип Замещения Лискоу (Liskov's Substitution Principle)


Производные типы должны быть способны полностью замещаться их базовыми типами.

Этот принцип есть всего лишь расширение Принципа Открытости-Закрытости в условиях поведения, означающего, что мы должны быть уверены, что новые производные классы являются расширением базовых классов без изменения их поведения. Новые производные классы должны быть способны заменять базовые классы без каких-либо изменений в коде.
Принцип Замещения Лискоу был введён на 1987 Conference on Object Oriented Programming Systems Languages and Applications, in Data abstraction and hierarchy.

Last Updated ( Thursday, 27 March 2008 )

Перевод на русский язык Мурата Джусупова

Оригинальный текст на английском языке взят из http://www.oodesign.com/design-principles.html

Знакомство с компилятором GCC

Средствами, традиционно используемыми для создания программ для открытых операционных систем, являются инструменты разработчика GNU. Сделаем маленькую историческую справку. Проект GNU был основан в 1984 году Ричардом Столлманом. Его необходимость была вызвана тем, что в то время сотрудничество между программистами было затруднено, так как владельцы коммерческого программного обеспечения чинили многочисленные препятствия такому сотрудничеству. Целью проекта GNU было создание комплекта программного обеспечения под единой лицензией, которая не допускала бы возможности присваивания кем-то эксклюзивных прав на это ПО. Частью этого комплекта и является набор инструментов для разработчика, которым мы будем пользоваться, и который должен входить во все дистрибутивы Linux.

 

Одним из этих инструментов является компилятор GCC. Первоначально эта аббревиатура расшифровывалась, как GNU C Compiler. Сейчас она означает – GNU Compiler Collection.

Создадим первую программу с помощью GCC. По сложившейся традиции первая программа будет просто выводить в консоли приветствие «Hello world!» – «Здравствуй Мир!».

Файлы с исходными кодами программ, которые мы будем создавать, это обычные текстовые файлы, и создавать их можно с помощью любого текстового редактора (например GEdit KWrite, Kate, а также более традиционные для пользователей Linux – vi и emacs). Помимо текстовых редакторов, существуют специализированные среды разработки со своими встроенными редакторами. Одним из таких средств является KDevelop. Интересно, что в нём есть встроенный редактор и встроенная консоль, расположенная прямо под редактором. Так что можно прямо в одной программе, не переключаясь между окнами, и редактировать код и давать консольные команды.

Создайте отдельный каталог hello. Это будет каталог нашего первого проекта. В нём создайте текстовый файл hello.c со следующим текстом:

#include < stdio.h >

 

int main(void)

{

printf("Hello world!\n");

return(0);

}

Затем в консоли зайдите в каталог проекта. Наберите команду

gcc hello.c

Теперь посмотрите внимательно, что произошло. В каталоге появился новый файл a.out. Это и есть исполняемый файл. Запустим его. Наберите в консоли:

./a.out

Программа должна запуститься, то есть должен появиться текст:

Hello world!

Компилятор gcc по умолчанию присваивает всем созданным исполняемым файлам имя a.out. Если хотите назвать его по-другому, нужно к команде на компиляцию добавить флаг -o и имя, которым вы хотите его назвать. Давайте наберём такую команду:

gcc hello.c -o hello

Мы видим, что в каталоге появился исполняемый файл с названием hello. Запустим его.

./hello

Как видите, получился точно такой же исполняемый файл, только с удобным для нас названием.

Флаг -o является лишь одним из многочисленных флагов компилятора gcc. Некоторые другие флаги мы рассмотрим позднее. Чтобы просмотреть все возможные флаги, можно воспользоваться справочной системой man. Наберите в командной строке:

man gcc

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

Вы, конечно, обратили внимание, что, когда мы запускаем программу из нашего каталога разработки, мы перед названием файла набираем точку и слэш. Зачем же мы это делаем?

Дело в том, что, если мы наберём только название исполняемого файла, операционная система будет искать его в каталогах /usr/bin и /usr/local/bin, и, естественно, не найдёт. Каталоги /usr/bin и /usr/local/bin – системные каталоги размещения исполняемых программ. Первый из них предназначен для размещения стабильных версий программ, как правило,входящих в дистрибутив Linux. Второй – для программ, устанавливаемых самим пользователем (за стабильность которых никто не ручается). Такая система нужна,чтобы отделить их друг от друга. По умолчанию при сборке программы устанавливаются в каталог /usr/local/bin. Крайне нежелательно помещать что-либо лишнее в /usr/bin или удалять что-то оттуда вручную, потому что это может привести к краху системы. Там должны размещаться программы, за стабильность которых отвечают разработчики дистрибутива.

Чтобы запустить программу, находящуюся в другом месте, надо прописать полный путь к ней, например так:

/home/dima/projects/hello/hello

Или другой вариант: прописать путь относительно текущего каталога, в котором вы в данной момент находитесь в консоли. При этом одна точка означает текущий каталог, две точки – родительский. Например, команда ./hello запускает программу hello, находящуюся в текущем каталоге, команда ../hello – программу hello, находящуюся в родительском каталоге, команда ./projects/hello/hello – программу во вложенных каталогах, находящихся внутри текущего.

Есть возможность добавлять в список системных путей к программам дополнительные каталоги. Для этого надо добавить новый путь в системную переменную PATH. Но давайте пока не будем отвлекаться от главной темы. Переменные окружения – это отдельный разговор.

Теперь рассмотрим, что же делает программа gcc. Её работа включает три этапа: обработка препроцессором, компиляция и компоновка (или линковка).

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

Вторая стадия – компиляция. Она заключается в превращении текста программы на языке C/C++ в набор машинных команд. Результат сохраняется в объектном файле. Разумеется, на машинах с разной архитектурой процессора двоичные файлы получаются в разных форматах, и на одной машине невозможно запустить бинарник, собранный на другой машине (разве только, если у них одинаковая архитектура процессора и одинаковые операционные системы). Вот почему программы для UNIX-подобных систем распространяются в виде исходных кодов: они должны быть доступны всем пользователям, независимо от того, у кого какой процессор и какая операционная система.

Последняя стадия – компоновка. Она заключается в связывании всех объектных файлов проекта в один, связывании вызовов функций с их определениями, и присоединением библиотечных файлов, содержащих функции, которые вызываются, но не определены в проекте. В результате формируется запускаемый файл – наша конечная цель. Если какая-то функция в программе используется, но компоновщик не найдёт место, где эта функция определена, он выдаст сообщение об ошибке, и откажется создавать исполняемый файл.

Теперь посмотрим на практике, как всё это выглядит. Напишем другую программу. Это будет примитивнейший калькулятор, способный складывать, вычитать, умножать и делить. При запуске он будет запрашивать по очереди два числа, над которыми следует произвести действие, а затем потребует ввести знак арифметического действия. Это могут быть четыре знака: «+», «–», «*», «/». После этого программа выводит результат и останавливается (возвращает нас в операционную систему, а точнее – в командный интерпретатор, из которого мы программу и вызывали).

Создадим для проекта новую папку kalkul, в ней создадим файл kalkul.c.

#include < stdio.h >

 

int main(void)

{

float num1;

float num2;

char op;

 

printf("Первое число: ");

scanf("%f",&num1);

 

printf("Второе число: ");

scanf("%f",&num2);

 

printf("Оператор ( + - * / ): ");

while ((op = getchar()) != EOF)

{

if (op == '+')

{

printf("%6.2f\n",num1 + num2);

break;

}

else if(op == '-')

{

printf("%6.2f\n",num1 - num2);

break;

}

else if(op == '*')

{

printf("%6.2f\n",num1 * num2);

break;

}

else if(op == '/')

{

if(num2 == 0)

{

printf("Ошибка: деление на ноль!\n");

break;

}

else

{

printf("%6.2f\n",num1 / num2);

break;

}

}

}

 

return 0;

}

Итак, первым делом, как было сказано, выполняется препроцессинг. Для того, чтобы посмотреть, что на этом этапе делается, воспользуемся опцией -E. Эта опция останавливает выполнение программы на этапе обработки препроцессором. В результате получается файл исходного кода с включённым в него содержимым заголовочных файлов.

В нашем случае мы включали один заголовочный файл – stdio.h – коллекцию стандартных функций ввода-вывода. Эти функции и выводили на консоль нужный текст, а также считывали с консоли вводимые нами слова.

Введите следующую команду:

gcc -E kalkul.c -o kalkul.cpp

Полученному файлу мы дали имя kalkul.cpp. Откройте его. Обратите внимание на то, что он весьма длинный. Это потому что в него вошёл весь код заголовочного файла stdio.h. Кроме того, препроцессор сюда добавил некоторые теги, указывающие компилятору способ связи с объявленными функциями. Основной текст нашей программы виден только в самом низу.

Можете заодно посмотреть, какие ещё функции объявлены в заголовочном файле stdio.h. Если вам захочется получить информацию о какой-нибудь функции, можно поинтересоваться о ней во встроенном руководстве man. Например, если вам вдруг захочется узнать, что же делает таинственная функция fopen, можно набрать:

man fopen

Много информации также есть в справочной системе info.

info fopen

Можно поинтересоваться и всем заголовочным файлом сразу.

man stdio.h

info stdio.h

Посмотрим теперь следующий этап. Создадим объектный файл. Объектный файл представляет собой «дословный» перевод нашего программного кода на машинный язык, пока без связи вызываемых функций с их определениями. Для формирования объектного файла служит опция -c.

gcc -c kalkul.c

Название получаемого файла можно не указывать, так как компилятор просто берёт название исходного и меняет расширение .c на .o (указать можно, если нам захочется назвать его по-другому).

Если мы создаём объектный файл из исходника, уже обработанного препроцессором (например, такого, какой мы получили выше), то мы должны обязательно указать явно, что компилируемый файл является файлом исходного кода, обработанный препроцессором, и имеющий теги препроцессора. В противном случае он будет обрабатываться, как обычный файл C++, без учёта тегов препроцессора, а значит связь с объявленными функциями не будет устанавливаться. Для явного указания на язык и формат обрабатываемого файла служит опция -x. Файл C++, обработанный препроцессором обозначается cpp-output.

gcc -x cpp-output -c kalkul.cpp

Наконец, последний этап – компоновка. Получаем из объектного файла исполняемый.

gcc kalkul.o -o kalkul

Можно его запускать.

./kalkul

Вы спросите: «Зачем вся эта возня с промежуточными этапами? Не лучше ли просто один раз скомандовать gcc kalkul.c -o kalkul?»

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

[ опубликовано 06/09/2006 ]

Дмитрий Пантелеичев (dimanix2006 at rambler dot ru) - Знакомство с компилятором GCC

Материал взят из http://www.linuxcenter.ru/lib/books/linuxdev/linuxdev1.phtml?style=print

Антипаттерны

Материал из Википедии — свободной энциклопедии

Анти-паттерны (anti-patterns), также известные как ловушки
(pitfalls) — это классы наиболее часто внедряемых плохих решений
проблем. Они изучаются, как категория, в случае когда их хотят избежать
в будущем, и некоторые отдельные случаи их могут быть распознаны при
изучении неработающих систем.


Термин происходит из информатики, из книги «Банды четырёх» Шаблоны проектирования, которая заложила примеры практики хорошего программирования. Авторы назвали эти хорошие методы «шаблонами проектирования», и противоположными им являются «анти-паттерны». Частью хорошей практики программирования является избежание анти-паттернов.



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




Некоторые различаемые анти-паттерны в программировании



Анти-паттерны в управлении разработкой ПО


  • Дым и зеркала
    (Smoke and mirrors): Демонстрация того, как будут выглядеть
    ненаписанные функции (название происходит от двух излюбленных способов,
    которыми фокусники скрывают свои секреты).
  • Раздувание ПО (Software bloat): Разрешение последующим версиям системы требовать всё больше и больше ресурсов.
  • Функции для галочки:
    Превращение программы в конгломерат плохо реализованных и не связанных
    между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть).



Анти-паттерны в разработке ПО




Анти-паттерны в объектно-ориентированном программировании



  • Базовый класс-утилита (BaseBean): Наследование функциональности из класса-утилиты вместо делегирования к нему
  • Вызов предка
    (CallSuper): Для реализации прикладной функциональности методу
    класса-потомка требуется в обязательном порядке вызывать те же методы
    класса-предка.
  • Ошибка пустого подкласса (Empty subclass failure): Создание класса (Perl),
    который не проходит «проверку пустоты подкласса» («Empty Subclass
    Test») из-за различного поведения по сравнению с классом, который
    наследуется от него без изменений
  • Божественный объект (God object): Концентрация слишком большого количества функций в одиночной части дизайна (классе)
  • Объектная клоака (Object cesspool): Переиспользование объектов, чьё состояние не удовлетворяет (возможно неявному) контракту переиспользования.
  • Полтергейст (компьютер) (Poltergeist): Объекты, чьё единственное предназначение — передавать информацию другим объектам
  • Проблема йо-йо (Yo-yo problem): Структура (например: наследования) которая тяжело понятна вследствие избыточной фрагментации
  • Синглетонизм (Singletonitis): Избыточное использование паттерна синглетон



Анти-паттерны в программировании


  • Ненужная сложность (Accidental complexity): Внесение ненужной сложности в решение
  • Действие на расстоянии (Action at a distance): Неожиданное взаимодействие между широко разделёнными частями системы
  • Накопить и запустить (Accumulate and fire): Установка параметров подпрограмм в наборе глобальных переменных
  • Слепая вера (Blind faith): Недостаточная проверка (a) корректности исправления ошибки или (b) результата работы подпрограммы
  • Лодочный якорь (Boat anchor): Сохранение более не используемой части системы
  • Активное ожидание (Busy spin): Потребление ресурсов ЦПУ

    (процессорного времени) во время ожидания события, обычно при помощи
    постоянно повторяемой проверки, вместо того, чтобы использовать систему
    сообщений
  • Кэширование ошибки (Caching failure): Забывать сбросить флаг ошибки после её обработки
  • Проверка типа вместо интерфейса
    (Checking type instead of membership, Checking type instead of
    interface): Проверка того, что объект имеет специфический тип в то
    время, когда требуется только определённый интерфейс
  • Инерция кода (Code momentum): Сверхограничение части системы путём постоянного подразумевания её поведения в других частях системы
  • Кодирование путём исключения (Coding by exception): Добавление нового кода для поддержки каждого специального распознанного случая
  • Таинственный код (Cryptic code): Использование аббревиатур вместо мнемоничных имён
  • Жёсткое кодирование (Hard code): Внедрение предположений об окружении системы в слишком большом количестве точек её реализации
  • Мягкое кодирование

    (Soft code): Патологическая боязнь жёсткого кодирования, приводящая к
    тому, что настраивается всё что угодно, при этом конфигурирование
    системы само по себе превращается в программирование.
  • Поток лавы
    (Lava flow): Сохранение нежелательного (излишнего или
    низкокачественного) кода по причине того, что его удаление слишком
    дорого или будет иметь непредсказуемые последствия
  • Магические числа (Magic numbers): Включение чисел в алгоритмы без объяснений
  • Процедурный код (Procedural code): Когда другая парадигма является более подходящей
  • Спагетти-код (Spaghetti code): Системы, чья структура редко понятна, особенно потому что структура кода используется неправильно
  • Мыльный пузырь (Soap bubble): Класс, инициализированый мусором, максимально долго притворяется, что содержит какие-то данные.



Методологические анти-паттерны





Анти-паттерны управления конфигурацией


  • Ад зависимостей (Dependency hell): Проблемы с версиями требующихся продуктов, особенно в системах UNIX/GNU/Linux
  • DLL-ад (DLL hell): Проблемы с версиями, доступностью и увеличением количества DLL, особенно в Microsoft Windows.



Некоторые организационные анти-паттерны


  • Аналитический паралич (Analysis paralysis): Выделение непропорционально больших усилий в фазе анализа проекта
  • Дойная корова (Cash cow): Закрытый продукт, приносящий выгоду, часто ведёт к самоуспокоенности относительно новых продуктов
  • Продолжительное устаревание (Continuous obsolescence): Выделение непропорционально больших усилий портированию системы в новые окружения
  • Сваливание расходов (Cost migration): Перенос расходов на проект к уязвимому отделу или бизнес-партнёру
  • Ползущий улучшизм (Creeping featurism): Добавление новых улучшений в ущерб качеству системы
  • Разработка комитетом (Design by committee): Результат того, что имеется много содействующих разработке, но не имеется единого видения
  • Эскалация обязательств (Escalation of commitment): Продолжение реализации решения в том случае, когда неправильность его доказана.
  • Я тебе это говорил (I told you so): Когда игнорируется предупреждение эксперта, являющееся оправданным
  • Управление числами

    (Management by numbers): Уделение избыточного внимания численным
    критериям управления, когда они неважны или стоимость их получения
    слишком высока
  • Драконовские меры (Management by perkele): Военный стиль управления без толерантности к диссидентству
  • Управление грибами (Mushroom management): Удержание работников в неинформированном и занятом состоянии
  • Расползание рамок (Scope creep): Дозволение рамкам проекта расти без должного контроля
  • Замкнутость на продавце (Vendor lock-in): Изготовление системы, избыточно зависящей от внешнего поставляемого компонента
  • Тёплое тело (Warm body): Человек, чей вклад в проект под сомнением, особенно если рассмотрен в панике
  • Единственный знающий человек

    (Single head of knowledge): ЕЗЧ (SHOK) применим в том случае, когда
    единственная личность во всей организации контролирует жизненно-важную
    область ноу-хау или информации о внутренностях системы.
  • Рыцарь на белом коне
    (Knight in shining armor): РНБК (KISA) происходит тогда, когда
    личность, которая не совершает ошибок, появляется на сцене и пытается
    починить всё, без сообщений о том, какие изменения он/она
    сделал/сделает и почему.


Некоторые социальные анти-паттерны


Статус некоторых из них может быть спорным.


  • Цензура (Censorship): Подавление дискуссии для предотвращения политического, социального и научного прогресса
  • Концентрация власти (Political corruption, Concentrated power): Индивидуальное злоупотребление властью, даже с изначально хорошими помыслами
  • Демократия

    (Democracy): Большая группа индивидов не может принимать
    аргументированные решения, а руководствуется лишь поверхностной
    информацией.
  • Диктатура (Dictatorship): Ни один индивид не имеет всех умений необходимых для управления; также власть развращает
  • Дискриминация (Discrimination): Концентрация на неуместных особенностях усиливает экономическую неэффективность и социальную напряжённость
  • Догма (Dogmatic religion): Догма подавляет индивидуальное мышление и тормозит прогресс
  • Нетерпимость
    (Intolerance): Настаивание на изменении нежелательных-но-безопасных
    особенностей других людей влечёт усиление напряжённости и также
    является бесконечной задачей
  • Монополия (Monopoly): Без соперничества большинство эффектов свободного рынка не работают, и частная компания не имеет стимула действовать честно
  • Система голосования на основе большинства

    (Plurality voting system): Политика при голосовании на основе
    большинства вырождается в две полярно-противоположные партии,
    результатом чего является подавление других политических воззрений
  • Соревнование в популярности
    (Popularity contest): Популярность становится самодостаточной величиной
    и не сопоставима ни с каким другими параметрами или достоинствами
  • Сегрегация (Racial segregation): Разделение по равноправию весьма редко, если вообще существует; ведёт к напряжённости
  • Однопартийная система (Single-party system): Без избирательного соревнования партия не имеет побуждения управлять честно
  • Тоталитаризм
    (Totalitarianism): Подавление индивидуальности ведёт к напряжённости,
    вдобавок одобренный способ жизни никогда ещё не был годен для всех
  • Преступление без жертв
    (Victimless crime): Подавление безопасного поведения создаёт
    субкультуру людей, постоянно-живущих-по-другим-законам, для которых эта
    правовая система является врагом
  • Охота на ведьм

    (Witch hunt): Легко отыскать козла отпущения, но если проблема никогда
    не решается в действительности, результатом будет являться поиск всё
    новых и новых козлов отпущения
  • Нулевой Год (Year Zero): Социальное изменение является долгим процессом, ускорение его влечёт катастрофу


Шуточные анти-паттерны


  • Паблик Морозов:
    Класс-потомок, созданный в соответствии с этим антипаттерном, выдает по
    запросу все данные класса-предка, независимо от степени их сокрытия.
    Название данного анти-паттерна — это каламбур, основанный на созвучии ключевого слова public
    (паблик), часто означающего открытый доступ к методам и полям класса в
    объектно-ориентированных языках программирования, и имени пионера-героя

    Павлика Морозова, известного тем, что он выдал своего отца-кулака.


Смотрите также



Обсуждение этой темы с моим знакомым программистом можно посмотреть на http://iphonesdk.livejournal.com/4153.html

Постоянные читатели

Архив блога