'Interface and implementation decoupling
I'm working on an cross-platform embedded project and I don't want to use abstract classes and virtual tables to separate interface from implementation.
I discovered this technique to decouple interface from implementation at compile time:
// interface
namespace iot {
template <class platform>
class uart {
public:
uart();
void methodA();
void methodB();
};
} // namespace iot
// implementation for avr8
class avr8;
template <>
class iot::uart<avr8> {
public:
void methodA() { std::cout << "avr8:A" << std::endl; }
void methodB() { std::cout << "avr8:B" << std::endl; }
};
// implementation form stm32
class stm32;
template <>
class iot::uart<stm32> {
public:
void methodA() { std::cout << "stm32:A" << std::endl; }
void methodB() { std::cout << "stm32:B" << std::endl; }
};
// chose platform
using platform = stm32;
// using platform = avr8;
// using platform = mock; // for unit tests
using uart = iot::uart<platform>;
int main() {
uart u1;
u1.methodA();
u1.methodB();
return 0;
}
Is this a good technique? Is there a simplier method to choose implementation at compile-time (not link-time) without using a templates?
Compare it with this example, which is almost the same, but without templates
// implementation for avr8
namespace avr8 {
class uart {
public:
void methodA() { std::cout << "avr8:A" << std::endl; }
void methodB() { std::cout << "avr8:B" << std::endl; }
};
}
namespace stm32 {
class uart {
public:
void methodA() { std::cout << "stm32:A" << std::endl; }
void methodB() { std::cout << "stm32:B" << std::endl; }
};
}
// choose platform
namespace platform = stm32;
// using platform = avr8;
// using platform = mock; // for unit tests
using uart = platform::uart;
int main() {
uart u1;
u1.methodA();
u1.methodB();
return 0;
}
Neither first nor second example doesn't enforce an interface.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|