Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last year.
Improve this question
I was wondering if empty overridden methods inherited from an abstract interface class are a sign of bad interface design. Sometimes interfaces contain methods that are useful only partially for all the possible implemention classes; in the classes where unused methods are not necessary, they are just left empty.
In the following example, connect() and disconnect() are common to the two implementation classes IpConnection and SmtpConnection. However, prepare() is not necessary in SmtpConnection and is left empty.
In this kind of situations, is it better to remove prepare() from the abstract interface IConnection and call it explicitly, or leave it empty? What if empty (unused) methods grow more and more?
#include <memory>
class IConnection
{
public:
virtual void connect() = 0; /* common */
virtual void disconnect() = 0; /* common */
virtual void prepare() = 0; /* partial */
};
class IpConnection : public IConnection
{
public:
void connect() override { /* ... */ }
void disconnect() override { /* ... */ }
void prepare() override { /* ... */ }
};
class SmtpConnection : public IConnection
{
public:
void connect() override { /* ... */ }
void disconnect() override { /* ... */ }
void prepare() override { } /* empty */
};
int main()
{
std::unique_ptr<IConnection> connection;
connection = std::make_unique<SmtpConnection>();
connection->connect();
connection->prepare();
connection->disconnect();
}
An interface is a type of 'contract' between two modules. Typically, an interface specifies how another module is allowed to make use of the functionality of the implementing module instance.
So in fact the interface has no business with the implementation itself. It just sets out the rules, possibly some induced flow constraints and protection provisions that any implementation must adhere to in order to provide a functional implementation.
So, if the interface needs to be overriden with an empty body, that' is totally fine. Other implementations may very well need to do work. Of course if you know that that is never going to happen, well perhaps is better not to over-design at that point, and just remove the interface call.
In your case I would not worry too much and leave it as an interface. Calling functionality directly makes sense ONLY if the overriding method is quite specific to the flow of that implementation, and less useful for other implementations to worry about.
Related
I'm having trouble finding best practice information about what I believe should be a fairly common problem pattern.
I will start with a specific (software update related) example, because it makes the discussion more concrete, but the issue should be fairly generic.
Say that I have a software updater interface:
struct Software_updater {
virtual ~Software_updater() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
For my first implementation A, I am lucky, everything is straightforward.
class A_software_updater : public Software_updater {
// ...
};
A B_software_updater, however, is more complicated. Like in the A-case, it is connected to the target to update in a non-trivial manner and maintains a target connection state. But more importantly, it can update two images: the application image, and the boot loader image.
Liking what I have so far, I see no real reason to go for a refactoring, so I assume I can just build upon it. I come up with the following solution:
class B_software_updater {
public:
Software_updater& application_updater() { return application_updater_; }
Software_updater& boot_loader_updater() { return boot_loader_updater_; }
private:
class Application_updater : public Software_updater {
// ...
} application_updater_;
class Boot_loader_updater : public Software_updater {
// ...
} boot_loader_updater_;
};
I.e. I am returning non-const references to "interfaces to" member variables. Note that they cannot be const, since they mute state.
Request 1: I think the solution above is a clean one, but I would be happy to get some confirmation.
In fact, I have recently faced the issue of having to optionally provide an interface in a class, based on compile-time selection of a feature, and I believe the pattern above is a solution for that problem too:
struct Optional_interface {
virtual ~Optional_interface() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
class A_implementation {
public:
#ifdef OPTIONAL_FEATURE
Optional_interface& optional_interface() { return optional_implementation_; }
#endif
// ...
private:
#ifdef OPTIONAL_FEATURE
class Optional_implementation : public Optional_interface {
// ...
} optional_implementation_;
#endif
// ...
};
Request 2: I could not find a simple (as in: not unnecessarily complicated template-based) and clean way to express a compile-time optional inheritance at the A_implementation-level. Can you?
Better solution
Based on a comment from #ALX23z about invalidation of member variable reference upon move, I am now rejecting my initial solution (original post). That invalidation problem would not be an issue for my case, but I am in search of a generic pattern.
As usual, the solution is obvious once one has found it.
First a summary of my initial problem.
Say that I have a software updater interface (or any interface, this is just an example):
struct Software_updater {
virtual ~Software_updater() = default;
virtual void action1(const Input1& input1) = 0;
virtual void action2() = 0;
virtual bool action3(const Input2& input2) = 0;
virtual Data1 info1() = 0;
virtual Data2 info2() = 0;
// etc.
};
A B_software_updater can update two images: an application image, and a boot loader image. Therefore, it wants to provide two instances of the Software_updater interface.
A solution that is better than the one in my original post is to declare a B_application_updater and a B_boot_loader_updater, constructed from a B_software_updater&, outside of B_software_updater, and instantiated by client code.
class B_application_updater : public Software_updater {
B_application_updater(B_software_updater&);
// ...
};
class B_boot_loader_updater : public Software_updater {
B_application_updater(B_boot_loader_updater&);
// ...
};
It does have the drawback of forcing the client code to create three objects instead of only one, but I think that the cleanliness outweighs that drawback.
This will work for the optional interface too (see original post):
class A_optional_implementation : public Optional_interface {
A_optional_implementation(A_implementation&);
};
A_optional_implementation will be declared outside of A_implementation.
Applications that do not need that interface will simply not instantiate A_optional_implementation.
Additional thoughts
This is an application of the adapter design pattern!
Basically, what this answer comes down to:
An Interface class.
An Implementation class that does the job, but does not really care about the interface. It does not inherit Interface. The point of this is that Implementation could "do the job" corresponding to several interfaces, without the complexity and drawbacks of multiple inheritance (name conflicts, etc.). It could also do the job corresponding to several instances of the same interface (my case above).
An Interface_adapter class that takes an Implementation& parameter in its constructor. It inherits Interface, i.e. it effectively implements it, and that is its only purpose.
Taking a step back, I realize that this is simply an application of the adapter pattern (although Implementationin this case does not necessarily need to implement any externally defined interface - its interface is just its public member functions)!
An intermediate solution: leave the adapter classes inside the implementation class
In the solution above, I specify that the adapter classes are declared outside of the implementation classes. While this seems logical for the traditional adapter pattern case, for my case, I could just as well declare them inside the implementation class (like I did in the original post) and make them public. The client code would still have to create the implementation and adapter objects, but the adapter classes would belong to the implementation namespace, which would look nicer.
I have a class representing some parameter. The parameter can be number, array, enum or bitfield - this is the param type. The behavior is slightly different between these types, so they are subclasses of paramBase class. The parameter can be stored in RAM or be static (i.e. hardcoded in some way, currently saved in a file).
void read() implemented in paramBase and uses template method pattern to implement reading for any param type, but this works only for RAM storage. If parameter is static then read() must be completely different (i.e. read from file).
A straightforward solution can be further subclassing like paramArrayStatic, paramNumberStatic, etc. (it will be 8 subclasses).
The difference between paramArray and paramArrayStatic is basically only in the read() method, so a straightforward solution will lead to code duplication.
Also I can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
class paramBase
{
public:
virtual paramType_t type() = 0;
paramStorage_t storage();
virtual someDefaultImplementedMethod()
{
//default implementation
}
void read()
{
//template method pattern
m_prop1 = blablabla;
someDefaultImplementedMethod();
}
protected:
paramStorage_t m_storage;
int m_prop1;
int m_prop2;
};
class paramArray: public paramBase
{
public:
virtual paramType_t type()
{
return PT_ARRAY;
}
virtual someDefaultImplementedMethod()
{
//overriding default implementation of base
//i.e. modify templated read() method behavior
}
protected:
int m_additional_prop1;
int m_additional_prop2;
};
In the end, I have 4 subclasses of base and I need to modify behavior of read() by static/non_static modificator.
How do I solve this without code duplication and code smell? Is the condition if( m_storage==static ) in read() is code smell or not?
You never have to duplicate code: just only re-implement that single method read. If you need to use it from pointers to the base class, virtual does just that. If you have common code between that 8 read method (or just between some of them), put it in a common middle layer.
If you want to make it clear that the class might not use the method at the base level, you can make it abstract, the add a ninth subclass for the RAM case.
Having a huge switch calling 9 different read methods in the same class seems far worse to me.
Straightforward solution can be furhter subclassing like paramArrayStatic, paramNumberStatic..etc. i.e. totally it will be 8 subclasses. Difference between paramArray and paramArrayStatic is basically only in read() method, so straightforward solution will lead to code duplication.
I agree. Creating a class that overrides the behaviour in such a significant way would be in violation of the SOLID principles (specifically the LSP part).
Also i can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
Who decides that this is code smell? It seems most expressive, and sensible to me.
Stop worrying so much about code smells, and start questioning the expressiveness of your options...
SigmaN,
For your simple example I would not worry about the control coupling in the read method. It is often better to have clear and maintainable code versus code that is strictly decoupled.
The general idea of your questions seems to be about decoupling the source of a value from the business logic for that value. Oftentimes, a good strategy is creating an interface as an ABC and then taking an instance on the the ctor. Here is a very simple example.
class ReadValue
{
public:
virtual int32_t readValue(std::string & value) = 0;
};
class DatabaseReadValue::public ReadValue
{
public:
virtual int32_t readValue(std:string & value) override; // read from the database
}
class XMLReadValue::public ReadValue
{
public:
virtual int32_t readValue(std::string & value) override; // read from XML file
}
class Parameter
{
public:
Parameter(ReadValue & readValueObj): readValueObj_(readValueObj) {}
int32_t read() { return(readValueObj_.readValue(value_)); }
ReadValue & readValueObj_;
std::string value_;
}
Oftentimes, the idea will be used in a template class rather than using inheritance. The gist is the same however.
The idea is related several Design Patterns depending on the details. Bridge, Adapter, Factory, Abstract Factory, PIMPL.
https://en.wikipedia.org/wiki/Software_design_pattern
--Matt
My problem is solved in this way:
//public interface and basic functionality
class base
{
public:
virtual void arraySize() //part of interface
{
printf("base arraySize()\n");
}
//template method read
int read()
{
readImpl();
}
protected:
virtual void readImpl() = 0;
};
//only base functionality of array is here. no read implementation!
class array : public base
{
public:
virtual void arraySize()
{
printf("array arraySize()\n");
}
};
//implement static read for array
class stat_array : public array
{
public:
void readImpl()
{
printf("stat_array read() \n");
}
};
//implement non static read for array
class nostat_array : public array
{
public:
void readImpl()
{
printf("nostat_array read() \n");
}
};
//test
stat_array statAr;
nostat_array nonstatAr;
base *statArPtr = &statAr;
base *nonstatArPtr = &nonstatAr;
void main()
{
statArPtr->read();
nonstatArPtr->read();
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm writing a physics engine in C++ and I've come to a stop, namely how I should design the class hierarchy. What I'm specifically concerned about is the World and Body classes. Body should expose some details to World that World then can work on. But at the same time, I don't want users to be able to access all of those properties of Body. But I still want users of the engine to be able to change some things in a body. For example, its position. How would you structure this in terms of classes?
Define an interface (i.e. a pure virtual class) that specifies what functions you want exposed from Body. Have Body implement that inteface.
Allow that interface, and not Body to be used from World.
This pattern is called composition.
Recently, I've solved a similar problem by introducing a special interface for the restricted operations, and inheriting protectedly from it. Like this:
struct RestrictedBodyFunctions
{
virtual void step() = 0;
virtual Body& asBody() = 0;
};
struct Body : protected RestrictedBodyFunctions
{
static std::unique_ptr<Body> createInWord(World &world)
{
auto Body = std::unique_ptr<Body>{new Body()};
world.addBody(*body); // cast happens inside Body, it's accessible
return std::move(body);
}
std::string getName() const;
void setName(std::string name);
protected:
void step() override
{ /*code here*/ }
Body& asBody() override
{ return *this; }
};
struct World
{
void addBody(RestrictedBodyFunctions &body)
{
m_bodies.push_back(&body);
}
void step()
{
for (auto *b : m_bodies)
{
myLog << "Stepping << " b->asBody().getName() << '\n';
b->step();
}
}
private:
std::vector<RestrictedBodyFunctions*> m_bodies;
};
That way, users can create Body objects using createInWorld, but they only get a handle to (the public part of) Body, while the World gets its handle to RestrictedBodyFunctions.
Another option you have is to reverse the above idea - provide a restricted public interface PublicBody, and have Body derive from PublicBody. Your internal classes will use the full Body, while factory functions make sure only PublicBody-typed handles are available to the clients. This alternative is a more simple design, but provides less control over who can access the full functionality.
I am designing a C++ module. This module can receive 3 different types of requests: Request-A, Request-B and Request-C.
For each type, I have a corresponding handler class: RequestHandler-A, RequestHandler-B and RequestHandler-C (all of these implement the IRequestHandler interface).
Each handler has to carry out certain actions to fulfill its request.
For example, RequestHandler-A needs to perform these in sequence:
Action-1
Action-2
Action-3
Action-4
Action-5
RequestHandler-B needs to perform these in sequence:
Action-1
Action-3
Action-5
RequestHandler-C needs to perform these in sequence:
Action-4
Action-5
The result of one action is used by the next one.
I am struggling to design these classes so that common action implementations are reused across handlers.
Are there any design patterns that can be applied here? Maybe Template method pattern could be a possibility but I am not sure.
Any suggestions would be greatly appreciated.
PS: to make things more interesting, there is also a requirement where, if Action-2 fails, we should retry it with different data. But maybe I am thinking too far ahead.
"Common implementations" means that your solution does not have anything to do with inheritance. Inheritance is for interface reuse, not implementation reuse.
You find that you have common code, just use shared functions:
void action1();
void action2();
void action3();
void action4();
void action5();
struct RequestHandlerA : IRequestHandler {
virtual void handle( Request *r ) {
action1();
action2();
action3();
}
};
struct RequestHandlerB : IRequestHandler {
virtual void handle( Request *r ) {
action2();
action3();
action4();
}
};
struct RequestHandlerC : IRequestHandler {
virtual void handle( Request *r ) {
action3();
action4();
action5();
}
};
Assuming that the common function are just internal helpers, you probably want to make them static (or use an anonymous namespace) to get internal linkage.
Are you looking for something like this?
#include <iostream>
using namespace std;
class Interface{
public:
void exec(){
//prepare things up
vExec();
//check everything is ok
};
virtual ~Interface(){}
protected:
virtual void vExec() = 0;
virtual void Action0() = 0;
virtual void Action1(){}
void Action2(){}
};
void Interface::Action0(){
}
void Action3(){}
class HandlerA : public Interface{
protected:
virtual void vExec(){
Action0();
Action1();
Action3();
}
virtual void Action0(){
}
};
class HandlerB : public Interface{
protected:
virtual void vExec(){
Action0();
Action1();
Action2();
Action3();
}
virtual void Action0(){
Interface::Action0();
}
};
int main()
{
Interface* handler = new HandlerA();
handler->exec();
HandlerB b;
b.exec();
delete handler;
}
As you can see the actions can be virtual members, non-virtual members, free functions, or whatever you might think of, depending on what you need.
The "additional" feature of feeding the actions with different data can be performed in exec() (if it is generic) or in vExec (if it is handler specific). If you give us more details I can modify the example accordingly.
Also, you can make vExec public and get rid of exec. The one in the example is just a practice I like most (making interface non-virtual and virtual functions non-public).
You can have one base class which implements the 5 actions and have the handlers derive from it.
If the actions are sufficiently isolated from each other, you can probably separate them out into individual functions or classes too and just have the handler call those.
Have you considered the Chain Of Command design pattern?
http://en.wikipedia.org/wiki/Command_pattern
It is a time proven pattern that promotes loose coupling among handler objects and the requests(commands) they receive.
What you could do is translate the request objects to act as Command Objects. You then specify which type of Commands each of your Handler's can undertake. You can then pass the command to the Handlers and have them pass the command forward if they cannot handle them. If a handler can handle the action, then the command is processed through each of its respective Actions. You can then have each logical action reside within the Handler as objects themselves, utilizing composition.
Okay, so you have a load of methods sprinkled around your system's main class. So you do the right thing and refactor by creating a new class and perform move method(s) into a new class. The new class has a single responsibility and all is right with the world again:
class Feature
{
public:
Feature(){};
void doSomething();
void doSomething1();
void doSomething2();
};
So now your original class has a member variable of type object:
Feature _feature;
Which you will call in the main class. Now if you do this many times, you will have many member-objects in your main class.
Now these features may or not be required based on configuration so in a way it's costly having all these objects that may or not be needed.
Can anyone suggest a way of improving this?
EDIT: Based on suggestion to use The Null Object Design Pattern I've come up with this:
An Abstract Class Defining the Interface of the Feature:
class IFeature
{
public:
virtual void doSomething()=0;
virtual void doSomething1()=0;
virtual void doSomething2()=0;
virtual ~IFeature(){}
};
I then define two classes which implement the interface, one real implementation and one Null Object:
class RealFeature:public IFeature
{
public:
RealFeature(){};
void doSomething(){std::cout<<"RealFeature doSomething()"<<std::endl;}
void doSomething1(){std::cout<<"RealFeature doSomething()"<<std::endl;}
void doSomething2(){std::cout<<"RealFeature doSomething()"<<std::endl;}
};
class NullFeature:public IFeature
{
public:
NullFeature(){};
void doSomething(){std::cout<<"NULL doSomething()"<<std::endl;};
void doSomething1(){std::cout<<"NULL doSomething1()"<<std::endl;};
void doSomething2(){std::cout<<"NULL doSomething2()"<<std::endl;};
};
I then define a Proxy class which will delegate to either the real object or the null object depending on configuration:
class Feature:public IFeature
{
public:
Feature();
~Feature();
void doSomething();
void doSomething1();
void doSomething2();
private:
std::auto_ptr<IFeature> _feature;
};
Implementation:
Feature::Feature()
{
std::cout<<"Feature() CTOR"<<std::endl;
if(configuration::isEnabled() )
{
_feature = auto_ptr<IFeature>( new RealFeature() );
}
else
{
_feature = auto_ptr<IFeature>( new NullFeature() );
}
}
void Feature::doSomething()
{
_feature->doSomething();
}
//And so one for each of the implementation methods
I then use the proxy class in my main class (or wherever it's required):
Feature _feature;
_feature.doSomething();
If a feature is missing and the correct thing to do is ignore that fact and do nothing, you can get rid of your checks by using the Null Object pattern:
class MainThing {
IFeature _feature;
void DoStuff() {
_feature.Method1();
_feature.Method2();
}
interface IFeature {
void Method1();
void Method2();
}
class SomeFeature { /* ... */ }
class NullFeature {
void Method1() { /* do nothing */ }
void Method2() { /* do nothing */ }
}
Now, in MainThing, if the optional feature isn't there, you give it a reference to a NullFeature instead of an actual null reference. That way, MainThing can always safely assume that _feature isn't null.
An auto_ptr by itself won't buy you much. But having a pointer to an object that you lazily load only when and if you need it might. Something like:
class Foo {
private:
Feature* _feature;
public:
Foo() : _feature(NULL) {}
Feature* getFeature() {
if (! _feature) {
_feature = new Feature();
}
return _feature;
}
};
Now you can wrap that Feature* in a smart pointer if you want help with the memory management. But the key isn't in the memory management, it's the lazy creation. The advantage to this instead of selectively configuring what you want to go create during startup is that you don't have to configure – you simply pay as you go. Sometimes that's all you need.
Note that a downside to this particular implementation is that the creation now takes place the first time the client invokes what they think is just a getter. If creation of the object is time-consuming, this could be a bit of a shock to, or even a problem for, to your client. It also makes the getter non-const, which could also be a problem. Finally, it assumes you have everything you need to create the object on demand, which could be a problem for objects that are tricky to construct.
There is one moment in your problem description, that actually would lead to failure. You shouldn't "just return" if your feature is unavailable, you should check the availability of your feature before calling it!
Try designing that main class using different approach. Think of having some abstract descriptor of your class called FeatureMap or something like that, which actually stores available features for current class.
When you implement your FeatureMap everything goes plain and simple. Just ensure (before calling), that your class has this feature and only then call it. If you face a situation when an unsupported feature is being called, throw an exception.
Also to mention, this feature-lookup routine should be fast (I guess so) and won't impact your performance.
I'm not sure if I'm answering directly to your question (because I don't have any ideas about your problem domain and, well, better solutions are always domain-specific), but hope this will make you think in the right way.
Regarding your edit on the Null Object Pattern: If you already have a public interface / private implementation for a feature, it makes no sense to also create a null implementation, as the public interface can be your null implementation with no problems whatsoever).
Concretely, you can have:
class FeatureImpl
{
public:
void doSomething() { /*real work here*/ }
};
class Feature
{
class FeatureImpl * _impl;
public:
Feature() : _impl(0) {}
void doSomething()
{
if(_impl)
_impl->doSomething();
// else case ... here's your null object implementation :)
}
// code to (optionally) initialize the implementation left out due to laziness
};
This code only benefits from a NULL implementation if it is performance-critical (and even then, the cost of an if(_impl) is in most cases negligible).