OutputPolicy моего класса иногда идет к статическому / одноэлементному объекту, а иногда к объекту 1-к-1.
Не уверен, смогу ли я объяснить по-английски .. так вот желаемое поведение в псевдокоде:
template<
class Algo,
template<class> OutputPolicy
>
class AlgoBase : Algo, OutputPolicy<Algo>
{
};
class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
NewMsg(msg);
}
};
class AlgoImp2
{
public:
AlgoImp2(string topic) {}
void OnData(
{
cout << " AlgoImp2::OnData";
if ( .... )
NewMsg(msg);
}
};
AlgoImp :: OnData выполняет некоторую обработку и вызывает NewMsg. Я пытаюсь отделить имплиментацию вызова NewMsg ().
template < class T>
class OutMessageQueueTcp
{
void NewMsg(string in)
{
//Should be a signgleton or static
cout << " OutMessageQueueTcp::NewMsg";
}
};
Если OutputPolicy — OutMessageQueueTcp (выше), тогда должен быть только один экземпляр OutputPolicy. Так что я должен был бы либо получить его из Singleton, либо где-нибудь использовать статическую переменную.
template <class T>
class OutMessageAsInput : AlgoBase<AlgoImp2, OutMessageQueueTcp>
{
void NewMsg(string in)
{
cout << " OutMessageAsInput::OnData";
AlgoBase<AlgoImp2, OutMessageQueueTcp>::NewMsg(in);
}
};
Если OutputPolicy имеет значение OutMessageAsInput (выше), тогда out становится входным для дочернего объекта и затем отправляется в OutMessageQueueTcp.
Вот главное.
main
{
AlgoBase<AlgoImp, OutMessageAsInput> myalgo1;
myalgo1.OnData("hi");
}
И мой желаемый результат:
AlgoImp::OnData
OutMessageAsInput::NewMsg
AlgoImp2::OnData
OutMessageQueueTcp::NewMsg
Что у меня действительно есть, так это коллекция объектов AlgoImp, каждый со своей темой и данными. AlgoImp генерирует outout, вызывая NewMsg. Иногда эти сообщения следует отправлять в Socket, а иногда они должны обрабатываться AlgoImp2.
Это решение будет принято во время компиляции. Каждый Алго будет делать разные вещи. Похоже, я пытаюсь сделать что-то вроде Аспект-ориентированного материала.
Вопрос:
Можно ли сделать базовый класс одноэлементным или обычным объектом, сделав его политикой? Есть ли шаблон дизайна для чего-то подобного? Может быть, какая-то фабрика?
Спасибо за помощь.
Чтобы все было просто — OutputPolicy
на вашем уровне классов algo должен быть простой класс с простым методом. Конечно, вы можете реализовать это с помощью одноэлементных или статических методов из реального класса реализации:
template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
impl.NewMsg(in);
}
private:
static OutMessageQueueTcpImpl<T> impl;
};
Или же:
template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
OutMessageQueueTcpImpl<T>::NewMsg(in);
}
};
Для тебя Algo*
классы: если политика вывода задана во время компиляции — сделайте шаблон этих классов классным и обработайте OutputPolicy как Strategy
— keeo оно агрегируется (как переменная-член) в ваших алгоритмах:
template <template <typename> class OutputPolicy>
class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
outputPolicy.NewMsg(msg);
}
private:
OutputPolicy<AlgoImp> outputPolicy;
};
Других решений пока нет …