M
ma740988
I'm going through modern C++ design looking for tips and while hi-tech
I suspect one solution to my issue would involve the factory design
pattern.
// algorithms.h
class Algorithms {
protected:
typedef std::deque<double> DDEQUE; // need to make this even more
generic to support floats .. i.e float and double
public:
virtual ~Algorithms() {};
virtual double mean1( const DDEQUE& queue );
virtual double mean2( const DDEQUE& queue );
// FFT and all sorts of funny math _stuff_
};
/////////// algorithms.hpp
#include "algorithms.hpp"
#include <iostream>
#include <numeric>
#ifndef NDEBUG
# define PRINT_CALLING_FUN() std::cout << __func__ << "() was called"
<< std::endl
#else
# define PRINT_CALLING_FUN()
#endif
double Algorithms::mean1( const DDEQUE& queue )
{
double val = std::accumulate ( queue.begin(), queue.end(), 0. ) /
queue.size();
PRINT_CALLING_FUN();
return val;
}
double Algorithms::mean2( const DDEQUE& queue )
{
double val = std::accumulate ( queue.begin(), queue.end(), 0. ) /
queue.size();
PRINT_CALLING_FUN();
return val;
}
I realize, there's no difference between mean1 and mean2 but they're
there for illustration purposes.
------------------------------------------------------------------------------------------------------
I've got two classes Ying and Yang.
Yang will use/is only interested in mean2 from Algorithm and Ying will
use/is only interested in mean1 from Algorithm. The current approach:
class Algorithms_Ying : public Algorithms {
public:
double mean1( const DDEQUE& queue ) {}
};
class Algorithms_Yang : public Algorithms {
public:
double mean2( const DDEQUE& queue ) {}
};
class Yang {
private:
typedef std::deque<double> DDEQUE;
Algorithms *alg;
public:
Yang(Algorithms *a) {alg = a;};
virtual ~Yang() {};
void test(const DDEQUE& q) { alg->mean2(q); }
};
class Ying {
private:
typedef std::deque<double> DDEQUE;
Algorithms *alg;
public:
Ying(Algorithms *a) {alg = a;};
virtual ~Ying() {};
void test(const DDEQUE& q) { alg->mean1(q); }
};
int main{}
{
Algorithms_Ying a1;
Algorithms_Yang a2;
Ying ying(&a1);
Yang yang(&a2);
}
That today seems silly and _appears_ like a maintenance nightmare.
What I'm trying to determine is a way to have (may not be saying this
right) a factory of algorithms, then have Ying/Yang or whomever go
inside and literally pull out what they want. You see, I receive from
the _outside_ world composite type (literally) YingStuff and
YangStuff.
enum ALGO { mean1, mean2, FFT, IFFT }; // etc etc
struct YingToDo { ALGO enum; };
struct YangToDo { ALGO enum; };
struct YingStuff { YingToDo todo[ 5 ] ; } ;
struct YangStuff { YingToDo todo[ 5 ] ; } ;
The tricky piece to this though surrounds the fact that I can't do -
for example - a mean1 on Yang. The point being the outside world will
need to ensure the YingStuff and YangStuff composites are filled out
properly. Simply put the factory I suspect could return an object that
contains the necessary functions and if I'm asked to do something I'm
can't do I wont do it.
The question. How would I achieve this? Source snippet or pseudo code
would help me better envision the design.
Thanks
I suspect one solution to my issue would involve the factory design
pattern.
// algorithms.h
class Algorithms {
protected:
typedef std::deque<double> DDEQUE; // need to make this even more
generic to support floats .. i.e float and double
public:
virtual ~Algorithms() {};
virtual double mean1( const DDEQUE& queue );
virtual double mean2( const DDEQUE& queue );
// FFT and all sorts of funny math _stuff_
};
/////////// algorithms.hpp
#include "algorithms.hpp"
#include <iostream>
#include <numeric>
#ifndef NDEBUG
# define PRINT_CALLING_FUN() std::cout << __func__ << "() was called"
<< std::endl
#else
# define PRINT_CALLING_FUN()
#endif
double Algorithms::mean1( const DDEQUE& queue )
{
double val = std::accumulate ( queue.begin(), queue.end(), 0. ) /
queue.size();
PRINT_CALLING_FUN();
return val;
}
double Algorithms::mean2( const DDEQUE& queue )
{
double val = std::accumulate ( queue.begin(), queue.end(), 0. ) /
queue.size();
PRINT_CALLING_FUN();
return val;
}
I realize, there's no difference between mean1 and mean2 but they're
there for illustration purposes.
------------------------------------------------------------------------------------------------------
I've got two classes Ying and Yang.
Yang will use/is only interested in mean2 from Algorithm and Ying will
use/is only interested in mean1 from Algorithm. The current approach:
class Algorithms_Ying : public Algorithms {
public:
double mean1( const DDEQUE& queue ) {}
};
class Algorithms_Yang : public Algorithms {
public:
double mean2( const DDEQUE& queue ) {}
};
class Yang {
private:
typedef std::deque<double> DDEQUE;
Algorithms *alg;
public:
Yang(Algorithms *a) {alg = a;};
virtual ~Yang() {};
void test(const DDEQUE& q) { alg->mean2(q); }
};
class Ying {
private:
typedef std::deque<double> DDEQUE;
Algorithms *alg;
public:
Ying(Algorithms *a) {alg = a;};
virtual ~Ying() {};
void test(const DDEQUE& q) { alg->mean1(q); }
};
int main{}
{
Algorithms_Ying a1;
Algorithms_Yang a2;
Ying ying(&a1);
Yang yang(&a2);
}
That today seems silly and _appears_ like a maintenance nightmare.
What I'm trying to determine is a way to have (may not be saying this
right) a factory of algorithms, then have Ying/Yang or whomever go
inside and literally pull out what they want. You see, I receive from
the _outside_ world composite type (literally) YingStuff and
YangStuff.
enum ALGO { mean1, mean2, FFT, IFFT }; // etc etc
struct YingToDo { ALGO enum; };
struct YangToDo { ALGO enum; };
struct YingStuff { YingToDo todo[ 5 ] ; } ;
struct YangStuff { YingToDo todo[ 5 ] ; } ;
The tricky piece to this though surrounds the fact that I can't do -
for example - a mean1 on Yang. The point being the outside world will
need to ensure the YingStuff and YangStuff composites are filled out
properly. Simply put the factory I suspect could return an object that
contains the necessary functions and if I'm asked to do something I'm
can't do I wont do it.
The question. How would I achieve this? Source snippet or pseudo code
would help me better envision the design.
Thanks