Новые книги

Работа сайта похожа на работу обычного магазина: если секции с разными товарами расположены логично, консультанты доступны в любой момент, а описания товаров информативны и понятны, есть шанс, что человек, зашедший в магазин, не уйдет с пустыми руками. Проанализируйте характеристики ваших потенциальных клиентов, поймите, что для них является ценностью, какие аргументы привлекут их внимание, соответственно этому продумайте структуру сайта, спроектируйте «маршрут» передвижения и составьте описания товаров – и ваши посетители будут гораздо чаще, чем сейчас, кликать на значок «корзины», а вы в разы повысите один из главных показателей работы сайта – конверсию. Авторы подробно рассказывают про основополагающие принципы, благодаря которым можно создать не только красивый, но и максимально эффективный сайт. Сайт, обеспечивающий продажи.
The agile model of software development has taken the world by storm. Now, in Agile Software Development, Second Edition, one of agiles leading pioneers updates his Jolt Productivity award-winning book to reflect all that?s been learned about agile development since its original introduction.

Alistair Cockburn begins by updating his powerful model of software development as a ?cooperative game of invention and communication.? Among the new ideas he introduces: harnessing competition without damaging collaboration; learning lessons from lean manufacturing; and balancing strategies for communication. Cockburn also explains how the cooperative game is played in business and on engineering projects, not just software development

Next, he systematically illuminates the agile model, shows how it has evolved, and answers the questions developers and project managers ask most often, including

· Where does agile development fit in our organization?

· How do we blend agile ideas with other ideas?

· How do we extend agile ideas more broadly?

Cockburn takes on crucial misconceptions that cause agile projects to fail. For example, you?ll learn why encoding project management strategies into fixed processes can lead to ineffective strategy decisions and costly mistakes. You?ll also find a thoughtful discussion of the controversial relationship between agile methods and user experience design.

Cockburn turns to the practical challenges of constructing agile methodologies for your own teams. You?ll learn how to tune and continuously reinvent your methodologies, and how to manage incomplete communication. This edition contains important new contributions on these and other topics:

· Agile and CMMI

· Introducing agile from the top down

· Revisiting ?custom contracts?

· Creating change with ?stickers?

In addition, Cockburn updates his discussion of the Crystal methodologies, which utilize his ?cooperative game? as their central metaphor.

If you?re new to agile development, this book will help you succeed the first time out. If you?ve used agile methods before, Cockburn?s techniques will make you even more effective.

Примеры.

Пример 27

/* Коммуникация процессов при помощи псевдо-терминала.
 *   Данная программа позволяет сохранять полный протокол работы
 *   экранной программы в файл.
 *   Не экранные программы данная версия НЕ трассирует,
 *   поскольку сама работает в "прозрачном" режиме.
 *
 * Вариацией данной программы может служить использование
 * системного вызова select() вместо запуска нескольких процессов.
 *
 * Программа также иллюстрирует "дерево" из 5 процессов.
 *            Данная версия написана для UNIX System V.
 *      TRACE__
 *  \          \           master    slave
 *  |экран<======\(Reader)=======!~!<====(целевая  )
 *  /     <==\      |            ! !====>(программа)
 *             \    |            !P!         |
 *              |   |            !T!         |
 *    . . . .   |   |            !Y!      (Slave)-->Управляет
 *   клавиатура=|===|=>(Writer)=>!_!         | \    семафором
 *              |   |       |                |   \
 *              |  #####starter##################  \
 *              |...................................|
 *                                ftty
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <termio.h>
#include <sys/stat.h>
#include <fcntl.h>
extern int  exit ();
extern char *ttyname ();
extern  FILE * fopen ();
extern errno;
#define SEMAPHORE "/tmp/+++"            /* семафорный файл */
#define TRACE     "TRACE"             /* файл с протоколом */
	     /* псевдотерминал связи */
/* master - это часть, которая ведет себя как ФАЙЛ и умеет
 * реагировать на некоторые специальные ioctl()-и */
#define PTY       "/dev/ptyp0"          /* master */
/* slave - это часть, которая ведет себя как драйвер терминалов */
#define TTYP      "/dev/ttyp0"          /* slave  */
int     ptyfd;
FILE * ftrace = NULL;
/* при прерывании завершить работу процесса "писателя" */
onintr () {
    closeVisual ();
    fprintf (stderr, "\rwriter finished\r\n");
    exit (0);
}
/* завершение работы процесса-"читателя" */
bye () {
    if (ftrace)
	fclose (ftrace);
    fprintf (stderr, "\rreader finished\r\n");
    exit (0);
}
int     visual = 0;
struct termio   old,
		new;
/* настроить режимы работы терминала на "прозрачный" режим */
initVisual () {
    ioctl (0, TCGETA, &old);
    new = old;
    new.c_iflag &= ~ICRNL;
    new.c_lflag &= ~(ECHO | ICANON);
    new.c_oflag &= ~(TAB3 | ONLCR);
    new.c_cc[VMIN] = 1;
    new.c_cc[VTIME] = 0;
 /* new.c_cc[VINTR] = ctrl('C');   */
    new.c_cc[VQUIT] = 0;
    new.c_cc[VERASE] = 0;
    new.c_cc[VKILL] = 0;
}
/* включить прозрачный режим */
openVisual () {
    if (visual) return;
    visual = 1;
    ioctl (0, TCSETAW, &new);
}
/* выключить прозрачный режим */
closeVisual () {
    if (!visual) return;
    visual = 0;
    ioctl (0, TCSETAW, &old);
}
struct stat st;
main (argc, argv) char **argv; {
    int     r,          /* pid процесса-"читателя" */
	    w;          /* pid процесса-"писателя" */
    if (argc == 1) {
	fprintf (stderr, "pty CMD ...\n");
	exit (1);
    }
    initVisual ();
    if((ptyfd = open ( PTY , O_RDWR)) < 0){
	fprintf(stderr, "Cannot open pty\n"); exit(2);
    }
    /* запустить процесс чтения с псевдодисплея */
    r = startReader ();
    /* запустить процесс чтения с клавиатуры */
    w = startWriter ();
    sleep (2);
    /* запустить протоколируемый процесс */
    startSlave (argv + 1, r, w);
    /* дождаться окончания всех потомков */
    while (wait (NULL) > 0);
    exit (0);
}
/* запуск протоколируемого процесса */
startSlave (argv, r, w) char  **argv; {
    FILE * ftty;
    int     pid;
    int     tfd;
    char   *tty = ttyname (1);   /* полное имя нашего терминала */
    if (!(pid = fork ())) {
    /* PTY SLAVE process */
	ftty = fopen (tty, "w"); /* Для выдачи сообщений */
	setpgrp ();       /* образовать новую группу процессов ;
			   * лишиться управляющего терминала */
	/* закрыть стандартные ввод, вывод, вывод ошибок */
	close (0);
	close (1);
	close (2);
	/* первый открытый терминал станет управляющим для процесса,
	 * не имеющего управляющего терминала.
	 * Открываем псевдотерминал (slave) в качестве стандартных
	 * ввода, вывода и вывода ошибок
	 */
	open ( TTYP, O_RDWR);
	open ( TTYP, O_RDWR);
	tfd = open ( TTYP, O_RDWR);
	if (tfd < 0) {
	    fprintf (ftty, "\rSlave: can't read/write pty\r\n");
	    kill(r, SIGKILL); kill(w, SIGKILL); exit (1);
	}
	/* запускаем целевую программу */
	if (!(pid = fork ())) {
	    fprintf (ftty, "\rCreating %s\r\n", SEMAPHORE);
	    fflush (ftty);
	    /* создаем семафорный файл */
	    close (creat (SEMAPHORE, 0644));
	    fprintf (ftty, "\rStart %s\r\n", argv[0]);
	    fclose(ftty);
	    /* заменить ответвившийся процесс программой,
	     * указанной в аргументах
	     */
	    execvp (argv[0], argv);
	    exit (errno);
	}
	/* дожидаться окончания целевой программы */
	while (wait (NULL) != pid);
	/* уничтожить семафор, что является признаком завершения
	 * для процессов чтения и записи
	 */
	unlink (SEMAPHORE);
	fprintf (ftty, "\rDied.\r\n");
	fflush (ftty);
    /* убить процессы чтения и записи */
    /* terminate reader & writer */
	kill (r, SIGINT); kill (w, SIGINT);
	exit (0);
    }
    return pid;
}
 /* Пара master-процессов чтения и записи */
/* запуск процесса чтения с псевдотерминала (из master-части) */
startReader () {
    char    c[512];
    int     pid;
    int n;
    if (!(pid = fork ())) {
    /* читать данные с ptyp на экран и в файл трассировки */
	signal (SIGINT, bye);
	/* ожидать появления семафора */
	while (stat (SEMAPHORE, &st) < 0);
	fprintf (stderr, "\rReader: Hello\r\n");
	ftrace = fopen (TRACE, "w");
	/* работать, пока существует семафорный файл */
	while (stat (SEMAPHORE, &st) >= 0) {
	    /* прочесть очередные данные */
	    n = read (ptyfd, c, 512);
	    if( n > 0 ) {
	       /* записать их на настоящий терминал */
	       fwrite( c, sizeof(char), n, stdout );
	       /* и в файл протокола */
	       fwrite( c, sizeof(char), n, ftrace );
	       fflush (stdout);
	    }
	}
	bye ();
    }
    return pid;
}
/* запуск процесса чтения данных с клавиатуры и записи
 * их на "псевдоклавиатуру". Эти данные протоколировать не надо,
 * так как их эхо-отобразит сам псевдотерминал
 */
startWriter () {
    char    c;
    int     pid;
    if (!(pid = fork ())) {
    /* читать клавиатуру моего терминала и выдавать это в ptyp */
	openVisual (); /* наш терминал - в прозрачный режим */
	signal (SIGINT, onintr);
	while (stat (SEMAPHORE, &st) < 0);
	fprintf (stderr, "\rWriter: Hello\r\n");
	/* работать, пока существует семафорный файл */
	while (stat (SEMAPHORE, &st) >= 0) {
	    read (0, &c, 1);            /* читать букву с клавиатуры */
	    write (ptyfd, &c, 1);       /* записать ее на master-pty */
	}
	onintr ();      /* завершиться */
    }
    return pid;
}

© Copyright А. Богатырев, 1992-95
Си в UNIX

Назад | Содержание | Вперед