Wrapper class design and dependency injection - c++

I have a simple FTP class that take care of downloading and uploading through cURL libraries:
class FTPClient
{
public:
explicit FTPClient(const std::string& strIPAddress);
virtual ~FTPClient();
bool DownloadFile(const std::string& strRemoteFile, const std::string& strLocalFile);
bool UploadFile(const std::string& strLocalFile, const std::string& strRemoteFile);
private:
static size_t WriteToFileCallBack(void *ptr, size_t size, size_t nmemb, FILE *stream);
static size_t ReadFromFileCallback(void* ptr, size_t size, size_t nmemb, FILE *stream);
std::string m_strUser;
std::string m_strPass;
std::string m_strIPAddress;
std::string m_strPort;
mutable CURL* m_objCurlSession;
};
I've asked some advices on how it could be implemented and structured better since it's the base and core for a project and it's going to be used in many parts.
I've been told to use a cURLWrapper class to wrap all of the cURL calls (curl_easy_setopt(..)), but then I've been told to create an Interface for the FTP class, a cURLWrapper that just calls the FTP methods and then a concrete class.. but still it's too abstract for me and don't understand the best way to implement it and which path to follow..
How would you approach this small structure?

Define a simple interface for your FTP class:
class IFTPClient
{
public:
virtual ~IFTPClient();
virtual bool DownloadFile(const std::string& strRemoteFile, const std::string& strLocalFile) = 0;
virtual bool UploadFile(const std::string& strLocalFile, const std::string& strRemoteFile) = 0;
};
I assume your static callback methods are calling back into some class instance rather than into a singleton? That's fine then. Derive your class from the interface:
class FTPClient:IFTPClient
{
...
I notice that you have the IP address passed into the constructor and have other parameters (user name, password, port, etc.) defined elsewhere. That does not appear to be quite consistent yet. You would need to refactor that so that these parameters can be set through interface methods or add those to the upload/download methods.
Construct your FTPClient object(s) before you need it elsewhere and then only pass ("inject") the interface into objects that want to use the FTPClient. For unit testing without the use of the actual FTPClient, construct a mock object derived from the same interface and inject that into other objects instead.
Other objects simply make use of the functionality exposed in the interface and don't need to know or worry about its internal implementation; if you decide to use curl or something else is then entirely up to FTPClient.
That's in in a nutshell; you may want to search for dependency injection and frameworks on the Internet but you don't need a framework to follow dependency injection principles and, in my opinion, they can be overkill for simple projects.

Related

Designing class for handling multiple communication protocols handling

I am developing a C++ application which should handle multiple communication protocols (Ethernet, Serial, etc.). Each of the communication protocols is handled as a specific class.
In order to expose as little as possible information about the internal structure and organization of the said classes and protocols, I would like to somehow wrap all of this functionality and provide somewhat generic API for sending data over a selected protocol.
Basically, what API should provide (the parameters are not restricted to this, but is the general idea):
bool sendData(uint8_t* buffer, const size_t& bufferSize);
void receiveData(uint8_t* dataBuffer, size_t& bufferSize);
What is the best way to create a generic API for the said functionality, and if possible involve some design pattern?
Regards.
What is the best way to create a generic API for the said
functionality, and if possible involve some design pattern?
The Strategy Pattern looks suitable in this scenario.
First, define an interface for all your distinct communication startegies, Communication:
class Communication {
public:
virtual ~CommunicationStrategy() = default;
virtual bool sendData(uint8_t* buffer, const size_t& bufferSize) = 0;
virtual void receiveData(uint8_t* dataBuffer, size_t& bufferSize) = 0;
};
Then, your concrete implementations – i.e., strategies – should derive from this interface:
class EthernetCommunication: public Communication {
public:
// ...
bool sendData(uint8_t*, const size_t&) override;
void receiveData(uint8_t*, size_t&) override;
};
class SerialCommunication: public Communication {
public:
// ...
bool sendData(uint8_t*, const size_t&) override;
void receiveData(uint8_t*, size_t&) override;
};
class CarrierPigeon: public Communication {
public:
// ...
bool sendData(uint8_t*, const size_t&) override;
void receiveData(uint8_t*, size_t&) override;
};
The client code will work with a (pointer to) Communication – i.e., the interface – rather than directly with a particular implementation like EthernetCommunication, SerialCommunication, or CarrierPigeon. Thus, the code follows the "program to an interface, not to an implementation" advice. For example, you may have a factory function like:
std::unique_ptr<Communication> CreateCommunication();
This factory function returns one of the strategies above. Which strategy to return can be determined at run time.
std::unique_ptr<Communication> com = CreateCommunication();
// send data regardless of a particular communication strategy
com->sendData(buffer, bufferSize);
This way, the code above isn't coupled to any particular implementation, but only to the interface Communication which is common to all the different possible communication strategies.
If the different communication strategies don't need per-instance data, just having two callbacks instead of an object will do:
using data_sender_t = bool (*)(uint8_t*, const size_t&);
using data_receiver_t = void (*)(uint8_t*, size_t&);
// set these function pointers to the strategy to use
data_sender_t data_sender;
data_receiver_t data_receiver;

C++/CLI: how to store a managed reference inside a native class?

In my mixed solution (C++/.NET), I'd like to pass instances of Log4Net's ILog to C++ objects (to unify logging across the solution).
I thought to write a C++ interface (LogInterface), and then implement a managed-to-unmanaged adapter in a C++/CLI project, but the problem is that the unmanaged adapter won't be able to store a field pointing to the managed ILog instance.
Is there an elegant, safe and performing way to achieve this (other than storing the managed reference inside a static cache)?
class UnmanagedLogAdapter :
public LogInterface
{
public:
UnmanagedLogAdapter(log4net::ILog^ log);
virtual bool IsInfoEnabled(void) const override
{
return m_log->IsInfoEnabled();
}
virtual void Info(const std::wstring& message) override
{
log4net::ILog^ log = m_log; // alternative that I want to avoid: log = StaticCache::Find(m_logId);
log->Info(gcnew System::String(message.cstr()));
}
private:
log4net::ILog^ m_log; //TODO: a managed field is forbidden
};
Use a gcroot<ILog^> member, as described here.

Preferred way to serialize an object with C++

Java has a very simple way to serialize objects. couldn't find something similar in C++.
I found Boost Serialization, and a basic approach using ifstream and ofstream.
I have a Task class wich has a title, id, status and date/time. I want to implement a serialize function within the class to save that object in binary mode.
But I want to save multiple instances of the class on a single binary file. Let's say, a Task array.
Would it be a good approach to implement a serialize method on the class? It will only serialize one at a time and It doesn't looks well-done if I use ifstream/ofstream, as I'll be opening and closing files a lot. Also every task will be saved on different files.
Boost's serialization looked fine, but is best for me to avoid 3rd party dependencies if possible.
What would be the best way of accomplish this?
My class header:
#ifndef TASK_H
#define TASK_H
class Task {
public:
enum Status { COMPLETED, PENDIENT };
Task(std::string text);
~Task();
// SETTERS
void setText(std::string text);
void setStatus(Status status);
// GETTERS
const std::string getText() const;
const bool getStatus() const;
const int getID() const;
const int getCount() const;
const std::string getDate() const;
const std::string getTime() const;
// DATE
const int getDay() const;
const int getMonth() const;
const int getYear() const;
// TIME
const int getSecond() const;
const int getMinute() const;
const int getHour() const;
// UTILS
//serialize
const void printFormatted() const;
// OVERLOAD
bool operator==( const Task &text2 ) const;
private:
void setID();
static int sCount;
int id;
std::string text;
Status status;
tm *timestamp;
};
#endif
If you only have a single, very simple class to serialise out, it's not that hard to implement a serialisation function that writes out the handful of members that you need to save. You don't give a code example that shows your class, but with a handful of members it should be comparatively easy as long as there are no pointers involved. If you write out the number of objects serialised followed by the data contained therein, that would probably be good enough for your purposes.
If you want to implement the serialisation yourself, I would have an external function (possibly a friend of your class) handle the serialisation of the Task array rather than trying to put the array serialisation into your class. What you can do is add a serialiseObject() function to your class that serialises a single object, then call it repeatedly from the array serialisation function. That's a much cleaner design than having the array serialisation also bolted onto the class itself.
Once you get into serialising C++ object that are a little more complex, especially ones containing references and pointers, serialisation very quickly becomes a hard problem and you really, really want to use an existing, third-party mechanism that has been well tested.
That said, as someone who does C++ development for a living, I consider a dependency on boost as normal, not a third party library I would want to avoid. Boost gives you so much additional functionality that I consider it part of "my standard library".
Since there is no standard for serializing data in C++, the "preferred" way is what you prefer. Boost is entirely acceptable, unless your project explicitly prohibits the use of third-party libraries, in which case you can certainly roll your own.
If you choose to roll your own, make sure that your serializers and deserializers do not open and close the streams on their own. Instead, the callers need to pass the stream to them. See this link for more information.
I have also used Google protobuf for serialization. While not strictly serialization, Google protobuf can be nicely efficient and cross platform for containers of data.

Best way to expose API from a library

I am designing a Win32 library to parse the contents of the file (Columns and Values) and store it internally in a datastructure (Map). Now i need to expose API's so that the consumer can call those API's to get the results.
The file may have different formats eg FM1, FM2 etc. The consumer may query like
FM1Provider.GetRecords("XYZ");
FM2Provider.GetRecords("XYZ");
What i am planning to do is to have a CParser class that does all the parsing and expose the class.
CParser
{
bool LoadFile(string strFile);
Map<string,string> GetFM1Records(string key);
Map<string,string> GetFM1Records(string key);
};
or
class CResultProvider
{
virtual Map<string,string> GetRecords(string key)=0;
}
class CFM1ResultProvider : public CResultProvider
{
Map<string,string> GetRecords(string key);
}
class CFM2ResultProvider : public CResultProvider
{
Map<string,string> GetRecords(string key);
}
CParser
{
bool LoadFile(string strFile);
CResultProvider GetFM1ResultProvider();
CResultProvider GetFM1ResultProvider();
};
Please suggest me which one of these approaches are correct and scalable considering i am developing a library.
Your component seems to be dealing with two problems: parsing and storing. It is a good design practise to separate these into different components so that they can be used independently.
I would suggest you provide the parser only with callbacks for parsed data. This way the user of it can choose the most suitable container for her application, or may choose to apply and discard read data without storing.
E.g.:
namespace my_lib {
struct ParserCb {
virtual void on_column(std::string const& column) = 0;
virtual void on_value(std::string const& value) = 0;
protected:
~ParserCb() {} // no ownership through this interface
};
void parse(char const* filename, ParserCb& cb);
} // my_lib
BTW, prefer using namespaces instead of prefixing your classes with C.
Assuming the client would only have to call GetRecords once, and then work with the map, the first approach I prefer the first approach because it is simpler.
If the client has to reload the map in different places in his code, the second approach is preferable, because it enables the client to write his code against one interface (CResultProvider). Thus, he can easily switch the file format simply by selecting a different implementation (there should be exactly one place in his code where the implementation is chosen).

OO Design - polymorphism - how to design for handing streams of different file types

I've little experience with advanced OO practices, and I want to design this properly as an exercise. I'm thinking of implementing the following, and I'm asking if I'm going about this the right way.
I have a class PImage that holds the raw data and some information I need for an image file. Its header is currently something like this:
#include <boost/filesytem.hpp>
#include <vector>
namespace fs = boost::filesystem;
class PImage
{
public:
PImage(const fs::path& path, const unsigned char* buffer, int bufferLen) :
path_(path), filesize_(bufferLen),
data_(buffer, buffer + filesize_),
width_(0), height_(0) {}
const vector<char> data() const { return data_; }
const char* rawData() const { return &data_[0]; }
/*** other assorted accessors ***/
private:
fs::path path_;
int filesize_;
vector<char> data_;
int width_;
int height_;
}
I want to fill the width_ and height_ by looking through the file's header. The trivial/inelegant solution would be to have a lot of messy control flow that identifies the type of image file (.gif, .jpg, .png, etc) and then parse the header accordingly.
Instead of using vector<char> data_, I was thinking of having PImage use a class, RawImageStream data_ that inherits from vector<char>. Each type of file I plan to support would then inherit from RawImageStream, e.g. RawGifStream, RawPngStream.
Each RawXYZStream would encapsulate the respective header-parsing functions, and PImage would only have to do something like height_ = data_.getHeight();.
Am I thinking this through correctly?
How would I create the proper RawImageStream subclass for data_ to be in the PImage ctor? Is this where I could use an object factory?
Anything I'm forgetting?
Yes, you could implement your class hierarchy in the way you describe. Nevertheless, I would probably have had PngImage, GifImage and JpegImage derive directly from PImage. PImage can then become abstract:
class PImage
{
virtual ~PImage {}
virtual unsigned int getWidth() const = 0
virtual unsigned int getHeight() const = 0
...
};
Then, each concrete image type implements getWidth and getHeight.
The PImage class can then be created by a PImage factory:
boost::shared_ptr<PImage> createImage(const fs::path& path);
In the factory, you pretty much open the file, look what type it has, and create the concrete image class passing the data in the constructor, to finally return the image as the abstract PImage.
Finally, I'd like to add that you should not worry too much about your design up front, and be ready to refactor later when you discover that your design does not fulfil your needs. That's through trial and error that you will grow a feeling for what design is proper for your problem!
You should have a look at the strategy pattern.
I would create an AbstractImage class containing pure virtual functions getHeight and getWidth();
Then I would override these functions in for example GifImage, JpegImage and PngImage (which all inherit from AbstractImage).
Then what you make a factory (factory pattern wikipedia ;)), which creates the correct concrete class for you depending on the filename.
So this would be something like
static AbstractImage* CreateImage(_fileName)
{
switch(getExtension(_fileName))
{
case ".gif":
return new GifImage(_fileName);
case ".jpg":
return new JpgedImage(_filename);
}
}
So beside in this function, you dont have to worry about the actual derived type you're using. You can do everything with the interface AbstractImage provides and polymorphism does the rest for you.