which design pattern to use to get the wanted functionality - c++

I want to make a pure virtual class that other classes inherit and each class implements the same function but with different implementation:
let say I implement class Server
class Server
{
Server();
~Server()=0;
virtual void send(const std::string& string);
virtual std::string receive();
};
class TcpServer:public Server
{
TcpServer();
~TcpServer();
void send(const std::string& string)
{...}
std::string receive(){...}
};
class UdpServer : public Server
{
UdpServer ();
~UdpServer ();
void send(const std::string& string)
{...}
std::string receive(){...}
};
main()
{
Server* server = new TcpServer()/UdpServer;
}
What's this Design Pattern called? because I don't understand if it's Adapter or Composite or Facade and if you have a different idea of how to implement this behavior.

Strategy pattern should be implemented for this use case. Check the link below for more information.
https://en.m.wikipedia.org/wiki/Strategy_pattern

I would lean more towards Factory Pattern:
https://en.m.wikipedia.org/wiki/Factory_method_pattern
Since you go into TCP/ UDP you might also check out the reactor pattern

Related

C++ Abstraction OOP (Inherit only some method to derived class)

Suppose i have a socket class:
class Socket{
public:
... Some Code ...
Socket(int type){
isServer = type;
//some code
}
virtual void Send(string s);
virtual void Send(string s, int clientID);
... Some Code ...
private:
int isServer;
};
This is to be used both as a server and client.
Now I need to have 2 Derived classes:
class ClientSocket : public Socket{
public:
... Some Code ...
};
class ServerSocket : public Socket{
public:
... Some Code ...
};
What I want is that ClientSocket will only have access to Send(string) and server socket will only have access to Send(string, int)
I checked some other answer:
https://stackoverflow.com/a/20997981/14911094
And that has a good idea of not using inheritance at all rather just encapsulate(Have a socket instance in server). But I want to know whether this can be done using Inheritance.
There is not absoulte way to doing such thing.
But here my idea:
create two class(like interface):
first class is server socket sender:
Class ServerSocketSender {
public:
virtual void Send(string s, int clientID);
}
second class is client socket sender:
Class ClientSocketSender {
public:
virtual void Send(string s);
}
due to interface segregation principle i recommend you to do such thing it is not wise choice to combine two send method in one class and enable desire method in desire class.
another trick that i saw many times but i dont know exactly if it's work in your case or not is something called SFINAE. with this trick i think you can achieve same thing but due to complexity i not recommend this approach.

Running into c++ virtual template function issue due to interface based programming

We are designing a new system where we have created interfaces for most of our classes so that we can create mocks (google mocks) for them for unit testing. As a result, all the functions are virtual but the issue is that I am often running into template virtual function issue due to this. I have seen some examples on how to do multi dispatch but they all seem to be using some variation of templates, it doesn't seem straightforward. So does it mean that my entire codebase will now end up with templates making it difficult to read/use and debug?
Or am I not designing good interfaces. Here is a simple example where I am writing an interface for a message queue.
Class IMessageQueue {
Public:
Virtual int send(const T & value); // I can't do this but this is exactly what I want to do, as send should be able to send any type
};
Class MessageQueue : public IMessageQueue {
Public:
Virtual int send(const T & value) { ... }
};
Class MockMQ : public IMessageQueue {
Public:
Virtual int send(const T & value) {
// mock implementation
}
};
How do I get around this problem? This is just one example but I run into lots of these type of issues due to interface based programming.
It depends if you need your IMessageQueue to dispatch specific unknown type or any type. That's not the same thing.
A specific unknown type can be managed by
template<typename T>
class IMessageQueue {
public:
virtual int send(const T& value);
}
So that you can have your IMessageQueue<MyMessage> and IMessageQueue<OtherMessage>.
If, instead, you need to be able to send any type with the same type of message queue then your option is to declare a specific interface common to all messages as in
class Message
{
protected:
Message() : { .. }
};
class MyMessage : public Message
{
..
};
class MessageQueue
{
public:
void send(const Message& message);
};

c++ using template and virtual method in one class

I have a little inheritance/template problem. I'm trying to create an interface IBinding which is implemented by a TcpClient and a TcpServer (there will be 2-3 different TcpServers which differ only in the type of Stream(Socket abstraction) they generate after accepting a connection request.
Here is a simplified example:
Interface:
struct IBinding
{
virtual ~IBinding() {}
virtual void bind(const std::string endpoint) = 0;
virtual void terminate() = 0;
};
typedef std::shared_ptr<IBinding> TBindingPtr;
Header:
#include "IBinding.h"
class TcpServer : public IBinding
{
public:
TcpServer();
~TcpServer();
virtual void bind(const std::string endpoint);
virtual void terminate();
};
Implementation:
#include "TcpServer.h"
#include "StreamTypeA.h"
#include "StreamTypeB.h"
TcpServer::TcpServer() { }
TcpServer::~TcpServer() { }
void TcpServer::terminate() { }
void TcpServer::bind(const std::string endpointStr)
{
auto stream = std::make_shared<StreamTypeA>(); // Here I need to use different types depending on the server implementation
}
Now, I want to create two instances of a TcpServer and call .bind() on them, but they should create different types of Streams.
a) As far as I understand, it's not possible to pass a Type to the bind() method as an argument in c++
b) Trying to define the bind method templated also doesn't work, because it is virtual
template<class TSocket>
virtual void bind(const std::string endpoint);
c) I could probably just create two different implementations of the TcpServer
Is there another way? Isn't there a way to do it with templates?
No. Template functions are inherently incompatible with virtual dispatch. You cannot override them. They can be name hidden, but that won't help you probably. So you either need to provide virtual functions for each stream type you will use, or create an abstraction for stream types that can be used at the IBinding level.

How to implement pure virtual functions with different parameter structures

I'm building a class with pure virtual functions called Database. The idea is to have a class that handles all the database interfaces (ie: open and close) and can be used on my business layers.
The Database class will be implemented in several 'flavours' for different databases, like mySqlDatabase and OracleDatabase.
I imagined Database having pure virtual methods with no code - just a header file as follows:
Database.hpp
class Database {
public:
Database();
virtual ~Database();
virtual void open(const std::string databasename) = 0;
virtual void open(const std::string databasename, const std::string username, const std::string password) = 0;
virtual void open(const std::string databasename, const std::string schema, const std::string username, const std::string password) = 0;
.
<Other stuff>
.
}
The three open variations are there to support different database connection requirements, from the simplest one (like Sqlite3 that needs only a filename), to Oracle (that needs all of that variables to connect).
I have some questions about the implementations (let's take oracle for example):
a) Shall I need to redeclare the virtual methods again on the derived class header file, like:
class OracleDatabase : public Database {
public:
OracleDatabase ();
virtual ~OracleDatabase ();
void open(const std::string databasename);
void open(const std::string databasename, const std::string username, const std::string password);
void open(const std::string databasename, const std::string schema, const std::string username, const std::string password);
}
b) How do I structure the implementation of the open methods in the derived class (let´s take Sqlite3)?
void Sqlite3Database::open(const std::string databasename){
...do some stuff...
}
void Sqlite3Database::open(const std::string databasename, const std::string username, const std::string password) {
...do some stuff...
}
void Sqlite3Database::open(const std::string databasename, const std::string schema, const std::string username, const std::string password) {
...do some stuff...
}
Am I using the right strategy? I've been browsing around virtual and pure virtual strategies and think this is the best approach for my problem.
Any suggestions/hints?
OBS: I'm coming from C# world so I do apologize if there is some misconception here.
For writing query functions (ie. same interface for all databases), pure virtual functions are the way to go.
Here, you are trying to write an open function, for which you might want to consider the Factory Design Pattern: you write your Database withour any open function; and you write a function such as static std::unique_ptr<Database> Sqlite3Database::open(/*...*/).
Using a virtual function like the one you are advocating is not a good idea: anyway you have 3 different functions that completely depend on the database that is used; and worse, your mother class depends on its children: to add a new database with another logging scheme, you have to add a function prototype to Database.
Another way to go would be to use a pure virtual function (preferably protected and called from constructor to preserve RAII; and following the NVI idiom) that takes as argument an initialization string such as the one used by PDO. Not exactly the same as anyway the database type can be inferred from the type instantiated, but the idea is to keep a single argument so as not to have multiple versions of open
(Old answer kept for the principles it tried to explain)
Actually you can do much easier: forget about open, and just do all of your initialization inside Sqlite3Database::Sqlite3Database(/* ... */).
After all, there is no way you can open a database without knowing which kind of DB it is (as you have to know a username/password, and even more: you have to know what arguments are required), so there is no sense in trying to make a virtual pure function out of this.
So, an example of what you could do:
class Database {
public virtual void create(/* ... */) = 0;
// ...
};
class Sqlite3Database : public Database {
Sqlite3Database(string filename);
public virtual void create(/* ... */) override;
// ...
};
class MySqlDatabase : public Database {
MySqlDatabase(int host, short port, string username, string password);
public virtual void create(/* ... */) override;
};

Dependency injection and event handling

class ITransportProvider
{
public:
virtual ~ITransportProvider() { }
protected:
virtual void SendData() = 0;
// Concrete TransportProvider will call OnReceiveDataEvent
// virtual void RegisterHandlers(std::function<void()> onReceiveDataEvent);
}
class Device
{
public:
Device(shared_ptr<ITransportProvider> transport)
: m_Transport(transport)
{
// transport->RegisterHandlers(boost::bind(&Device::OnReceiveData, this));
}
void SendData()
{
m_Transport->SendData();
}
// Which design pattern to use to get concrete TransportProvider's OnReceiveData event?
//void OnReceiveData()
//{
//}
private:
shared_ptr<ITransportProvider> m_Transport;
};
I've always added a "RegisterHandlers" in my ITransportProvider and make Device call it in its c'tor.
I'd like to know if its correctness in the eyes of DI/IoC gurus and would love to hear all suggestions.
EDIT:
To clarify, I'm asking if there's a better way of decoupling TransportProvider from Device besides the above way which is via DI and the Observer pattern.
You have a reasonable design. Decoupling can be handled at many different levels in different ways with various trade-offs. Your design is good for the case where you know the sending and receiving are related, but there is no particular compile-time relationship between Device instances and Transport implementations. If there was a compile-time relationship, you might use policy-based design:
class TransportProviderA
{
public:
void SendData();
virtual void OnReceiveData() = 0;
}
template <typename TransportPolicy>
class Device : public TransportPolicy
{
public:
Device(const TransportPolicy &transport_policy)
: TransportPolicy(transport_policy)
{
}
// SendData provided by TransportPolicy
virtual void OnReceiveData(); // overrides TransportPolicy's template method.
};
Then use it like this:
Device<TransportPolicyA> my_device(TransportPolicyA());