Would you consider using an interface and polymorphism to extend this design to be over-engineering?
Pros
Cons
My instinct is that, for this particular case, a single if
statement and a boolean flag is the superior option, but not everybody has agreed with me.
What do you think?
Original
// Connects to a local pipe, and naturally
// owns that connection
struct CommandWriter
{
CommandWriter() {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
~CommandWriter() {
close(fd);
};
// (Has useful member functions here)
private:
CommandWriter(CommandWriter const&); // Not relevant to question
int fd;
};
Extended with a boolean flag
// Adds a constructor where an FD can be specified
// from the call site, and no ownership is taken
struct CommandWriter
{
CommandWriter() : owns_fd(true) {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
CommandWriter(int fd) : fd(fd), owns_fd(false) {};
~CommandWriter() {
if (owns_fd)
close(fd);
};
// (Has useful member functions here)
private:
CommandWriter(CommandWriter const&); // Not relevant to question
int fd;
bool owns_fd;
};
Extended with polymorphism
// Sorry for the poor type names!
struct ICommandWriter
{
virtual ICommandWriter() {}
// (Has useful member functions here)
private:
ICommandWriter(ICommandWriter const&); // Not relevant to question
};
struct CommandWriter_Connects : ICommandWriter
{
CommandWriter_Connects() {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
~CommandWriter_Connects() {
close(fd);
};
// (Has useful member functions here)
private:
int fd;
};
struct CommandWriter_Uses : ICommandWriter
{
CommandWriter_Uses(int fd) : fd(fd) {};
~CommandWriter_Uses() {};
// (Has useful member functions here)
private:
int fd;
};
Overengineering (or over-engineering), is the act of designing a product or providing a solution to a problem in an elaborate or complicated manner, where a simpler solution can be demonstrated to exist with the same efficiency and effectiveness as that of the original design.
Definition of overengineer transitive + intransitive. : to engineer (something, such as a product) to have more functions, capabilities, etc. than are necessary or desirable The pressure to overreact to feedback … will lead many companies to overengineer their products, until common sense kicks back in.—
Other examples of overengineering are less positive. In the US, a start-up called Juicero developed a juicing press to squeeze out their pre-prepared juice pouches. The press cost over $400 and faced huge criticism when consumers discovered that the juice could be squeezed out just as effectively by hand.
According to Wikipedia, overengineering is "the act of designing a product to be more robust or have more features than often necessary for its intended use, or for a process to be unnecessarily complex or inefficient" To be honest, this is not very helpful - especially for software developers.
It depends on what you will use it for. If you have a big project and will use variants of the class many times then certainly it makes sense to make it flexible.
A rule of thumb:
Of course there are many exceptions, but that is a starting point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With