juan_gandhi: (Default)
[personal profile] juan_gandhi
Он не должен существовать! Это дебилизм.

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

1. Для производителя
2. Для потребителя

И было бы идиотизмом предъявлять сразу два; вместо этого, надо иметь что-то вроде:

BlockingQueue.ConsumerView
BlockingQueue.ProducerView

Очевидно, когда сказано, верно?

Только называть его надо не так; для консьюмера, что это очередь, не волнует; это просто Source, и вовсе не обязательно его использовать в блокирующем виде; а для продьюсера это Drain, и, вообще говоря, вовсе не блокирующий.

Что делает её блокирующей - это имплементация; но это не должно особо трахать ни ту ни другую сторону, они должны быть агностичны. Деметра, блин!

Date: 2011-10-30 08:32 pm (UTC)
From: [identity profile] sassa-nf.livejournal.com
а почему у List есть add и remove?

у Queue есть offer и poll, которые реализуют "неблокирующие" обращения, вроде add и remove; т.е. если add не работает (из-за ограничений по размеру, например), то и offer не работает.

далее вам нужно отличить offer от put.

Date: 2011-10-30 08:35 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Само собой, но это всё для продюсера.

Date: 2011-10-31 08:31 am (UTC)
From: [identity profile] sassa-nf.livejournal.com
ага. мне кажется 1. этот вопрос уже возникал раньше; 2. сродни вопросу, должен ли List иметь и add, и remove.

Date: 2011-10-30 08:36 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Да, [livejournal.com profile] antilamer об этом исчерпывающе писал в ПФП, кажется.

Date: 2011-10-30 09:01 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
О блин, я пропустил.

Странен, странен этот мир.

Date: 2011-10-30 10:27 pm (UTC)
From: [identity profile] sab123.livejournal.com
А смысл? Ну и если очень хочется, то всегда можно сделать. Например так:

class BlockingQueue
{
public:
    class ConsumerView
    {
    public:
        int consumerMethod()
        {
            return parent_->consumerMethod();
        }
    protected:
        friend class BlockingQueue;
        ConsumerView(BlockingQueue *parent):
            parent_(parent)
        { }

        BlockingQueue *parent_;
    };

    ConsumerView consumerView()
    {
        return this;
    }

    BlockingQueue()
    { }

protected:
    friend class ConsumerView;
    friend class ProducerView;

    int consumerMethod()
    {
        return 1;
    }
};

int main()
{
    BlockingQueue q;
    printf("%d\n", q.consumerView().consumerMethod());
}


Но толку от этого нету помимо проблем. Просто в определении класса поделить методы на группы - проще и полезнее. Например так:

class BlockingQueue
{
public:

    BlockingQueue()
    { }

    // *********************** consumer methods ***********************
    int consumerMethod()
    {
        return 1;
    }
    
    // *********************** producer methods ***********************
    int producerMethod()
    {
        return 2;
    }

};


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

Date: 2011-11-01 06:04 am (UTC)
nine_k: A stream of colors expanding from brain (Default)
From: [personal profile] nine_k
Мне просто кажется или "Demeter law" и "friend method" являют собой взаимоисключающие параграфы?

Date: 2011-11-01 02:13 pm (UTC)
From: [identity profile] sab123.livejournal.com
Что такое "Demeter law", я погуглил, и могу согласиться только частичтно. Во-первых, friend не методы а классы. Смысл их заключается в том, что частно нужно сделать несколько взаимосвязанных классов, которые вместе реализуют некую функциональность. И для связывания их друг с другом нужны внутренние интерфейсы, которые не должны быть видны снаружи. Но на самом деле при этом обычно бывает несколько таких внутренних интерфесов. Которые хотелось бы раздавать разным друзьям индивидуально. Типа, эти друзья могут вызывать эти методы, те друзья - те методы. А нынче оно все раздается оптом.

Date: 2011-10-30 10:29 pm (UTC)
From: [identity profile] sab123.livejournal.com
Блин, дочитал, и догадался, что речь идет просто о множественном наследовании :-) Так оно уже тоже есть. Ну, в Джаве - кривое, но все равно есть.

Date: 2011-10-30 11:07 pm (UTC)
From: [identity profile] jakobz.livejournal.com
Даже не нужно через свойства Consumer/ProducerView делать. Просто очередь должна реализовывать два интерфейса - на положить и на взять. И раздавать именно эти интерфейсы. Можно иметь и тот же самый IQueue, отнаследованный от обоих. Разумно, да.

Date: 2011-10-31 02:12 am (UTC)
From: [identity profile] vaddimka.livejournal.com
да по-моему не нужны толком никакие интерфейсы
просто давать хендлеры (типа объекты функции)
продьюсеру - на "положить"
консьюмеру - на "взять"
и реально не парит никого что там за реализация внутри у этих функций

Date: 2011-10-31 03:41 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
В принципе да, но в конкретном случае можно "положить" и "попробовать положить", так что интерфейс таки нужен.

Date: 2011-10-31 08:37 am (UTC)
From: [identity profile] sassa-nf.livejournal.com
имхо, правильный ответ - это что интерфейсы бывают двух видов:

1. what you declare (в т.ч. множ. наследование)
2. what I need

так вот, разница между 1 и 2 в том, что what I need в точности никто не реализует (а потому не declare). Но хорошо бы иметь способ объявить, что меня интересуют объекты, реализующие вот такие и сякие методы (объявление method signature) с вот такой и сякой семантикой (документация); у кого такие методы есть - они мне подходят. В скале, например, есть такое; кажется, constructed type называется.

В таком setting не нужно, чтобы дизайнер очереди догадался раскрошить наследование на всякие мелочи с разной группировкой одних и тех же методов. Достаточно объявить в типе аргумента, какая группа методов вас интересует.
From: [identity profile] hill-report.livejournal.com
именно блокируемость очереди будет определять реализацию консьюмера
ну обратился он к очереди а там нет ничего, что он должен делать
From: [identity profile] ivan-gandhi.livejournal.com
Нет, ну это-то может быть прописано в документации к put.

Date: 2011-10-31 08:00 am (UTC)
From: [identity profile] trurle.livejournal.com
А что происходит с консьемером когда очередь пуста?

Date: 2011-10-31 01:49 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Как что, всё то же; просто не надо консьюмерам показывать продьюсерский интерфейс.

Date: 2011-10-31 01:52 pm (UTC)
From: [identity profile] trurle.livejournal.com
Тоже - это что? Консьюмер блокируется в ожидании пока продьюсер(ы) наполнит очередь? Консьюмер получает специальное значение, выражающее отсутствие содержания в очереди? У очереди можно спросить пуста ли она?

Date: 2011-11-01 03:56 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Да нет! У BlockingQueue есть два набора методов, один для консьюмера, другой для продьюсера. Ну можно разделить на два интерфейса? Я нечего не предлагаю менять, я предлагаю отнять и поделить.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

July 2025

S M T W T F S
  12345
6789 1011 12
131415 1617 1819
20212223242526
2728 293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 31st, 2025 07:27 pm
Powered by Dreamwidth Studios