Re[2]: Сейчас глупый вопрос спрошу, только не обижайтесь
От: K13 http://akvis.com
Дата: 20.01.09 10:27
Оценка: 2 (1) +1
А>2, т.к. позволяет расширять набор транспортов не модифицируя зависимый от них класс (CMegaData), или модифицированный 1: CMegaData::Init(ITransport* t);

Я предпочел бы первый, заменив switch() на вызов фабрики.
Re: Сейчас глупый вопрос спрошу, только не обижайтесь
От: Аноним  
Дата: 20.01.09 10:12
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>Какой из вариантов более пацанский


2, т.к. позволяет расширять набор транспортов не модифицируя зависимый от них класс (CMegaData), или модифицированный 1: CMegaData::Init(ITransport* t);
Re: Сейчас глупый вопрос спрошу, только не обижайтесь
От: jazzer Россия Skype: enerjazzer
Дата: 20.01.09 10:30
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>Какой из вариантов более пацанский


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

В варианте с динамикой у тебя нарушено правило Single Responsibility, которое гласит, что каждый должен заниматься чем-то одним, а у тебя класс одновременно и с интерфейсом общается, и динамически выбирает, какой интерфейс ему создать.
Я в таких случаях бью все это на два (пользователь/фабрика) либо на три (пользователь/фабрика/фасад для объединения обоих) класса.
В варианте со статикой, вроде, проблем не видно.

В любом случае, смущает именование классов (интерфейс/данные) в соединении со схемой владения: почему это вдруг данные содержат интерфейс?
По идее, они вообще ничего о нем знать не должны.

Так что либо неудачное имя, либо ошибка дизайна.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Сейчас глупый вопрос спрошу, только не обижайтесь
От: frogkiller Россия  
Дата: 21.01.09 08:53
Оценка: 3 (1)
Здравствуйте, abrec, Вы писали:

A>Какой из вариантов более пацанский

A>
...
A>


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

Во-вторых, по примерам видно, что предполагается одинаковое использование классов, так что я бы предпочёл первый вариант — имхо наследование в этом случае лучше отражает "природу" задачи.

PS.
Хотя когда-то давно писал похожий велосипед — там у меня было много чего намешано шаблонного (всяких CRTP) и нешаблонного, получилось имхо красиво — но вот тому, кто сейчас этот код поддерживает, наверное, очень не хочется в нём разбираться Впрочем, насколько я знаю, за несколько лет повода не было
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: Сейчас глупый вопрос спрошу, только не обижайтесь
От: Аноним  
Дата: 20.01.09 15:42
Оценка: 1 (1)
Помимо прочего, в первом варианте есть ошибка.
Деструктор ITransport должен быть виртуальным, поскольку в CMegaData::~CMegaData() используется полиморфное разрушение:

Здравствуйте, abrec, Вы писали:
A>//**************Вариант 1*****************
A>class ITransport
A>{
A>public:
A>    ITransport(){};
A>    virtual ~ITransport(){};
A>    ...
Сейчас глупый вопрос спрошу, только не обижайтесь
От: abrec Россия  
Дата: 20.01.09 09:55
Оценка:
Какой из вариантов более пацанский
//**************Вариант 1*****************
class ITransport
{
public:
    ITransport(){};
    ~ITransport(){};
    virtual Init() = 0;
    virtual SendRequest(const char* pDataBuf, long lDataSize) = 0;
    virtual GetReply(const char* pDataBuf, long& lDataSize) = 0;
};

class CTCPIPTransport : public ITransport
{
public:
    CTCPIPTransport(){};
    ~CTCPIPTransport(){};
    virtual Init(){/*инициализирем сокет и т.д. и т.п.*/};
    virtual SendRequest(const char* pDataBuf, long lDataSize){/*шлем данные в сокет*/};
    virtual GetReply(const char* pDataBuf, long& lDataSize){/*принимаем данные из сокета*/};
};

class CRS232Transport : public ITransport
{
public:
    CRS232Transport(){};
    ~CRS232Transport(){};
    virtual Init(){/*инициализирем порт и т.д. и т.п.*/};
    virtual SendRequest(const char* pDataBuf, long lDataSize){/*шлем данные в порт*/};
    virtual GetReply(const char* pDataBuf, long& lDataSize){/*принимаем данные из порта*/};
};

class CMegaData
{
private:
    ITransport* m_pTransport;
public:
    CMegaData() : m_pTransport(NULL){};
    ~CMegaData()
    {
        if(m_pTransport)
            delete m_pTransport;
    };
    long Init(long lTrasportType)
    {
        switch(lTrasportType)
        {
        case 1:
            m_pTransport = new CTCPIPTransport();
            break;
        case 2:
            m_pTransport = new CRS232Transport();
            break;
        default:
            return -1;
        }
        m_pTransport->Init();
        return 0;
    }
    long Work()
    {
        long lBufSize = 10;
        char szBuf[10] = {0};
        memset(szBuf, 2, 10);
        m_pTransport->SendRequest(szBuf, lBufSize);
        m_pTransport->GetReply(szBuf, lBufSize);
        return 0;
    }
};

//Где-то в системе
{
    CMegaData theMegaData;
    theMegaData.Init(1);
    theMegaData.Work();
}
//**************Вариант 1*****************

//**************Вариант 2*****************

class CTCPIPTransport
{
public:
    CTCPIPTransport(){};
    ~CTCPIPTransport(){};
    virtual Init(){/*инициализирем сокет и т.д. и т.п.*/};
    virtual SendRequest(const char* pDataBuf, long lDataSize){/*шлем данные в сокет*/};
    virtual GetReply(const char* pDataBuf, long& lDataSize){/*принимаем данные из сокета*/};
};

class CRS232Transport
{
public:
    CRS232Transport(){};
    ~CRS232Transport(){};
    virtual Init(){/*инициализирем порт и т.д. и т.п.*/};
    virtual SendRequest(const char* pDataBuf, long lDataSize){/*шлем данные в порт*/};
    virtual GetReply(const char* pDataBuf, long& lDataSize){/*принимаем данные из порта*/};
};

template< typename TTransport >
class CMegaData
{
private:
    TTransport m_transport;
public:
    CMegaData() {};
    ~CMegaData(){};
    long Init()
    {
        m_transport.Init();
        return 0;
    }
    long Work()
    {
        long lBufSize = 10;
        char szBuf[10] = {0};
        memset(szBuf, 2, 10);
        m_transport.SendRequest(szBuf, lBufSize);
        m_transport.GetReply(szBuf, lBufSize);
        return 0;
    }
};

//Где-то в системе
{
    CMegaData< CTCPIPTransport > theMegaData;
    theMegaData.Init();
    theMegaData.Work();
}

//**************Вариант 2*****************
Re[2]: Сейчас глупый вопрос спрошу, только не обижайтесь
От: abrec Россия  
Дата: 20.01.09 10:36
Оценка:
Здравствуйте, jazzer, Вы писали:

J>В любом случае, смущает именование классов (интерфейс/данные) в соединении со схемой владения: почему это вдруг данные содержат интерфейс?

J>По идее, они вообще ничего о нем знать не должны.

J>Так что либо неудачное имя, либо ошибка дизайна.


Согласен. В реалии так.

class CBridge
{
private:
   ITransport*  m_pTransport;
   CTEDataBase* m_pDB;
};
Re: Сейчас глупый вопрос спрошу, только не обижайтесь
От: abrec Россия  
Дата: 20.01.09 11:16
Оценка:
Здравствуйте, abrec, Вы писали:

A>Какой из вариантов более пацанский


Сейчас поэкспериментировал есть соображения.
К примеру CMegaData надо расширить методом Work2()
****Вариант 1********
        long Work2()
    {
        long lBufSize = 10;
        char szBuf[10] = {0};
        memset(szBuf, 2, 10);
        m_pTransport->SendRequest(szBuf, lBufSize);
        m_pTransport->GetReply2(szBuf, lBufSize);
        return 0;
    }
****Вариант 1********
****Вариант 2********
        long Work2()
    {
        long lBufSize = 10;
        char szBuf[10] = {0};
        memset(szBuf, 2, 10);
        m_transport.SendRequest(szBuf, lBufSize);
        m_transport.GetReply2(szBuf, lBufSize);
        return 0;
    }
****Вариант 2********


В 1 варианте необходимо во всех классах *Transport внести реализацию GetReply2(szBuf, lBufSize)
Во 2 варианте только в те классы которыми инстанцированы (по моему так это называется) объекты СMegaData, зовущие GetReply2(szBuf, lBufSize)
Я ошибаюсь??
Re[2]: Сейчас глупый вопрос спрошу, только не обижайтесь
От: abrec Россия  
Дата: 20.01.09 15:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помимо прочего, в первом варианте есть ошибка.

А>Деструктор ITransport должен быть виртуальным, поскольку в CMegaData::~CMegaData() используется полиморфное разрушение:

А>Здравствуйте, abrec, Вы писали:

А>
A>>//**************Вариант 1*****************
A>>class ITransport
A>>{
A>>public:
A>>    ITransport(){};
A>>    virtual ~ITransport(){};
A>>    ...
А>


Согласен. Косячок
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.