Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Method chaining

Anna | 24.06.2014 | нет комментариев

В этом посте я побеседую о простом, но изредка пригодном приеме программирования — method chaining. Также расскажу про возможный подводный камень, связанный с его применением

Тест

Дабы было увлекательнее, вначале маленький тест.

1. Что такое method chaining? В суть этого приема?

2. Как он реализуется в С ?

3. Сумеете ли вы придумать допустимо опасную обстановку, связанную с импользованием этого приема?

Теория

Изредка, при применении либо написании крупных классов появляется надобность вызвать подряд несколько способов объекта этого класса. Традиционно это выглядит так:

class worker
{
	public:
	void set_data(const data_t& d);
	void process();
	void send_result();
	void print_log();
	...
};

void foo()
{
	worker w;
	w.set_data(data_t{});
	w.process();
	w.send_result();
	w.print_log();
	...
}

Прием method chaining разрешает сократить данный код. Для этого мы в всяком нашем способе возвратим ссылку на наш объект и выстроим вызовы в цепочку.

class worker
{
	public:
	worker& set_data(const data_t& d){...; return *this;}
	worker& process(){...; return *this;}
	worker& send_result(){...; return *this;}
	worker& print_log(){...; return *this;}
	...
};

void foo()
{
	worker w;
	w.set_data(data_t{}).process().send_result().print_log();
	...
}

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

Подводный камень

Сурово говоря, то что я опишу ниже относится не столько к method chaining, сколько к порядку вычисления доводов и вызовов функций, но тем не менее при применении “цепочки вызовов” эти правила на 1-й взор могут трудиться невзначай. Выходит.

struct worker 
{
    worker& process(int& i)
    {
        i = 185;
        return *this;
    }
    worker& print_result(const int& i)
    {
        std::cout <<"result: "<< i << std::endl;
        return *this; 
    }
};

int main()
{
    int data = 0;
    worker w;
    w.process(data).print_result(data 2);
}

Данный код скомпилируется без предупреждений и ошибок. Но итоги выполнения могут отличаться на различных компиляторах.
Дело в том, что правда эталон и гарантирует, что process() будет вызвана перед print_result(), но не гарантируется, что перед довод функции print_result будет вычислен позже выполнения process(). Соответственно, изредка в итоге выполнения этого кода может быть выведено “2”.

 

Источник: programmingmaster.ru

 

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB