what is the best way of sharing a configuration object across classes? - c++

Let us say that I have the classes M, A, B, C. M is the main class of my application (that is the one that does most of the job) and has this structure
class M {
public:
// Something here.
private:
Conifg config;
A a;
std::vector<B> bs;
const C* c;
};
In a main I create an instance m of class M and I want to set my config object, say by reading it from a file. The configuration object is nothing special, it could be a protocol buffer or a simple struct.
Now, I want a, b and c to be able to access the config object, because there are some global settings that they need. These settings are global, they do not change, and are the same for each instance of A, B and C (and M). What I am currently doing, is having a static field in each class A, B and C and I am setting a copy of the configuration object for each instance of these classes. I do not want these classes to know of the existence of M. Is this the best solution? Should I perhaps think of a global config variable?

Just pass the Config object to the A, B and C constructors (specifically, pass a reference to the Config object which is stored in M.
That gives you:
testability (you can easily swap out the config object for testing purposes
ease of reuse (you don't have "invisible" dependencies on globals that just have to be there. All A, B and C needs in order to exist are what they're given in their constructors
flexibility (you can create different config objects to pass to different classes, if you need to)
readability, because the person reading your code doesn't have to wonder "where does the config object come from? Who else might have changed it? Can I be sure it's been initialized at this point?". The classes A, B and C are self-contained, and can be read and understood in isolation.
But whatever you do, don't use a singleton, and try to avoid static/global data in general.

I would advice you to use an additional static class for configuration, instead of static fields in all the classes, where you include its header in the places you want.
Implement a static constructor where you initialize all the data you want in the static members. I think this would be a better solution.

I personally would rather somehow pass that config object to A B C than use global/static objects.
What about passing it (it's reference) as an argument upon construction of a b c, or setting it later via set_config() call?

I've found the most maintainable solutions for problems like these, are to use static function. If you use some object interface, hide it behind these functions.
Here is an example.
namespace config {
// public interface that is used a lot
bool GetConfigValue(const std::string &key, std::string &val);
}
namespace config {
namespace detail {
// detail interface that is used for setup and tear down
class Config {
public:
virtual ~Config() {}
virtual bool get(const std::string &key, std::string &val) = 0;
};
void RegisterConfig(Config *cfg);
void ResetConfig();
}}
Honestly, you'll have to change the interface eventually, and it's going to suck. The more you expose throughout the code, the higher risk it will be. So keep it simple.
As background, this is a cross-cutting concern which are typically annoying to deal with. You really don't want to pass these sorts of things around to your objects. Research into aspect oriented programming may be interesting, as they talk about the subject a lot.

Related

Should members of a class be turned static when more than one object creation is not needed?

class AA
{
public:
AA ();
static void a1 ();
static std :: string b1 ();
static std :: string c1 (unsigned short x);
};
My class won't have different objects interacting with among themselves or with others.
Of course I need to have at least one object to call the functions of this class, so I thought of making the members static so that unnecessary object creation can be avoided.
What are the pros and cons of this design? What will be a better design?
To access to static members, you don't even need an object, just call
AA::a1()
This patterns is called "Monostate", the alternative being Singleton, where you actually create an object, but make sure it's only done once, there are tons of tutorials on how to do that, just google it.
Should members of a class be turned static when more than one object creation is not needed?
You make members of the class static when you need only one instance of the member for all objects of your class. When you declare a class member static the member becomes per class instead of per object.
When you say you need only one object of your class, You are probably pointing towards the singleton design pattern. Note that pattern is widely considered an anti pattern and its usefulness if any is dependent to specific situations.
The reason you mention in Q is no way related to whether you should make a member static or not.
Your class has no data members, so I don't see any good reason to use a class at all:
namespace AA
{
void a1 ();
std :: string b1 ();
std :: string c1 (unsigned short x);
};
Of course I need to have at least one object to call the functions of this class
That's not true. You can call static member functions without an instance of the class.
A note on the Singleton pattern: it has a bad reputation, it is often mis-used, and in my experience it is only very rarely useful. What it does is enforce that there can only be one instance of the class, and that this instance is globally accessible.
People often think, "I only need one instance, therefore I should use Singleton", especially when Singleton is the first Capitalized Design Pattern they're introduced to. This is wrong -- if you only need one instance, create one instance and use it. Don't unnecessarily limit all future users of the class to only create one instance. Don't unnecessarily create shared global state. Both things make your code less flexible, harder to use in different ways and therefore in particular harder to test. Some people would argue that for these reasons, Singleton is strictly never useful.
In this case you don't seem to need even one instance. If that's the case I'd use free functions as above.

Dependency injection ; good practices to reduce boilerplate code

I have a simple question, and I'm not even sure it has an answer but let's try.
I'm coding in C++, and using dependency injection to avoid global state. This works quite well, and I don't run in unexpected/undefined behaviours very often.
However I realise that, as my project grows I'm writing a lot of code which I consider boilerplate. Worse : the fact there is more boilerplate code, than actual code makes it sometimes hard to understand.
Nothing beats a good example so let's go :
I have a class called TimeFactory which creates Time objects.
For more details (not sure it's relevant) : Time objects are quite complex because the Time can have different formats, and conversion between them is neither linear, nor straightforward. Each "Time" contains a Synchronizer to handle conversions, and to make sure they have the same, properly initialized, synchronizer, I use a TimeFactory. The TimeFactory has only one instance and is application wide, so it would qualify for singleton but, because it's mutable, I don't want to make it a singleton
In my app, a lot of classes need to create Time objects. Sometimes those classes are deeply nested.
Let's say I have a class A which contains instances of class B, and so on up to class D. Class D need to create Time objects.
In my naive implementation, I pass the TimeFactory to the constructor of class A, which passes it to the constructor of class B and so on until class D.
Now, imagine I have a couple of classes like TimeFactory and a couple of class hierarchies like the one above : I loose all the flexibility and readability I'm suppose to get using dependency injection.
I'm starting to wonder if there isn't a major design flaw in my app ...
Or is this a necessary evil of using dependency injection ?
What do you think ?
In my naive implementation, I pass the TimeFactory to the constructor
of class A, which passes it to the constructor of class B and so on
until class D.
This is a common misapplication of dependency injection. Unless class A directly uses the TimeFactory, it should not ever see, know about, or have access to the TimeFactory. The D instance should be constructed with the TimeFactory. Then the C instance should be constructed with the D instance you just constructed. Then the B with the C, and finally the A with the B. Now you have an A instance which, indirectly, owns a D instance with access to a TimeFactory, and the A instance never saw the TimeFactory directly passed to it.
Miško Hevery talks about this in this video.
Global state isn't always evil, if it's truly global. There are often engineering trade-offs, and your use of dependency injection already introduces more coupling than using a singleton interface or a global variable would: class A now knows than class B requires a TimeFactory, which is often more detail about class B than class A requires. The same goes for classes B and C, and for classes C and D.
Consider the following solution that uses a singleton pattern:
Have the TimeFactory (abstract) base class provide singleton access to the application's `TimeFactory:
Set that singleton once, to a concrete subclass of TimeFactory
Have all of your accesses to TimeFactory use that singleton.
This creates global state, but decouples clients of that global state from any knowledge of its implementation.
Here's a sketch of a potential implementation:
class TimeFactory
{
public:
// ...
static TimeFactory* getSingleton(void) { return singleton; }
// ...
protected:
void setAsSingleton(void)
{
if (singleton != NULL) {
// handle case where multiple TimeFactory implementations are created
throw std::exception(); // possibly by throwing
}
singleton = this;
}
private:
static TimeFactory* singleton = NULL;
};
Each time a subclass of TimeFactory is instantiated, you can have it call setAsSingleton, either in its constructor or elsewhere.

Is it good practice to create functions to access class variables?

As the title says: Is it good practice to create functions to access class variables?
I have seen quite a number of pieces of code that do something like the following:
class MyClass {
public:
void setx(int a);
void sety(int b);
int read_x;
int read_y;
private:
int x;
int y;
};
void MyClass::setx(int a) {
x=a;
}
void MyClass::sety(int b) {
y = b;
}
int MyClass::read_x() {
return x;
{
int MyClass::read_y() {
return y;
}
So rather than accessing variables directly(MyClass.x) they use functions to read and set the variable values etc.
Is this a standard or good practice?
Yes, accessor functions are preffered to direct member access for several reasons. They provide a unique access point, are easier to track and to debug.
For example, instead of setting a breakpoint everywhere in the code where MyClass.x is changed, you can just set a single breakpoint in MyClass::setX().
However, although better than direct member access, accessor methods are not without their drawbacks, if misused. For details, you can visit Getters and Setters are bad OO design?
Rather than access variables directly? Absolutely. Creating a programmatic interface layer decouples you from the implementation details of those internal variables themselves. You then afford yourself additional flexibility for things like creating mocked-out implementations of the class in question (for testing), creating proxy classes (for decorated functionality like logging, etc.)
I'd warn against automatically creating them for everything where you may not need them. But that's a different issue.
Much like working out at the gym: It gives back more than it takes ;)
Yes they are ok, however I would also say that you should keep your classes small than you would with say Java and what not so you don't end up with types that are mostly getters and setters.
Typically a class holds a (ideally single) state (which can be got if needed) and has an implementation which should ideally remain private.
This is important as it separates the interface of the class from the underlying data model. You often see basic code like the example you posted, and at first, a lot of it can seem like an unnecessary complication. However, it provides a (self documenting) framework where the implmentation of the object can be changed without breaking code that accesses the objects of the class via the defined interface.

C++ should all member variable use accessors and mutator

I have about 15~20 member variables which needs to be accessed, I was wondering
if it would be good just to let them be public instead of giving every one of them
get/set functions.
The code would be something like
class A { // a singleton class
public:
static A* get();
B x, y, z;
// ... a lot of other object that should only have one copy
// and doesn't change often
private:
A();
virtual ~A();
static A* a;
};
I have also thought about putting the variables into an array, but I don't
know the best way to do a lookup table, would it be better to put them in an array?
EDIT:
Is there a better way than Singleton class to put them in a collection
The C++ world isn't quite as hung up on "everything must be hidden behind accessors/mutators/whatever-they-decide-to-call-them-todays" as some OO-supporting languages.
With that said, it's a bit hard to say what the best approach is, given your limited description.
If your class is simply a 'bag of data' for some other process, than using a struct instead of a class (the only difference is that all members default to public) can be appropriate.
If the class actually does something, however, you might find it more appropriate to group your get/set routines together by function/aspect or interface.
As I mentioned, it's a bit hard to tell without more information.
EDIT: Singleton classes are not smelly code in and of themselves, but you do need to be a bit careful with them. If a singleton is taking care of preference data or something similar, it only makes sense to make individual accessors for each data element.
If, on the other hand, you're storing generic input data in a singleton, it might be time to rethink the design.
You could place them in a POD structure and provide access to an object of that type :
struct VariablesHolder
{
int a;
float b;
char c[20];
};
class A
{
public:
A() : vh()
{
}
VariablesHolder& Access()
{
return vh;
}
const VariablesHolder& Get() const
{
return vh;
}
private:
VariablesHolder vh;
};
No that wouldn't be good. Image you want to change the way they are accessed in the future. For example remove one member variable and let the get/set functions compute its value.
It really depends on why you want to give access to them, how likely they are to change, how much code uses them, how problematic having to rewrite or recompile that code is, how fast access needs to be, whether you need/want virtual access, what's more convenient and intuitive in the using code etc.. Wanting to give access to so many things may be a sign of poor design, or it may be 100% appropriate. Using get/set functions has much more potential benefit for volatile (unstable / possibly subject to frequent tweaks) low-level code that could be used by a large number of client apps.
Given your edit, an array makes sense if your client is likely to want to access the values in a loop, or a numeric index is inherently meaningful. For example, if they're chronologically ordered data samples, an index sounds good. Summarily, arrays make it easier to provide algorithms to work with any or all of the indices - you have to consider whether that's useful to your clients; if not, try to avoid it as it may make it easier to mistakenly access the wrong values, particularly if say two people branch some code, add an extra value at the end, then try to merge their changes. Sometimes it makes sense to provide arrays and named access, or an enum with meaningful names for indices.
This is a horrible design choice, as it allows any component to modify any of these variables. Furthermore, since access to these variables is done directly, you have no way to impose any invariant on the values, and if suddenly you decide to multithread your program, you won't have a single set of functions that need to be mutex-protected, but rather you will have to go off and find every single use of every single data member and individually lock those usages. In general, one should:
Not use singletons or global variables; they introduce subtle, implicit dependencies between components that allow seemingly independent components to interfere with each other.
Make variables const wherever possible and provide setters only where absolutely required.
Never make variables public (unless you are creating a POD struct, and even then, it is best to create POD structs only as an internal implementation detail and not expose them in the API).
Also, you mentioned that you need to use an array. You can use vector<B> or vector<B*> to create a dynamically-sized array of objects of type B or type B*. Rather than using A::getA() to access your singleton instance; it would be better to have functions that need type A to take a parameter of type const A&. This will make the dependency explicit, and it will also limit which functions can modify the members of that class (pass A* or A& to functions that need to mutate it).
As a convention, if you want a data structure to hold several public fields (plain old data), I would suggest using a struct (and use in tandem with other classes -- builder, flyweight, memento, and other design patterns).
Classes generally mean that you're defining an encapsulated data type, so the OOP rule is to hide data members.
In terms of efficiency, modern compilers optimize away calls to accessors/mutators, so the impact on performance would be non-existent.
In terms of extensibility, methods are definitely a win because derived classes would be able to override these (if virtual). Another benefit is that logic to check/observe/notify data can be added if data is accessed via member functions.
Public members in a base class is generally a difficult to keep track of.

Isn't the Factory pattern the same thing as global state?

Let's say I have a class like this:
class MonkeyFish
{
MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c);
private:
GlobalObjectA & m_a;
GlobalObjectB & m_b;
GlobalObjectC & m_c;
}
Without a factory, I need to do the following in order to instantiated a MonkeyFish.
GlobalObjectA a;
GlobalObjectB b;
GlobalObjectC c;
int main()
{
MonkeyFish * monkey_fish = new MonkeyFish(a, b, c);
monkey_fish->go();
}
On the other hand, if I have a MonkeyFishFactory, it seems like I have to do this:
GlobalObjectA a;
GlobalObjectB b;
GlobalObjectC c;
int main()
{
MonkeyFishFactory mf_factory(a, b, c);
MonkeyFish * monkey_fish = mf_factory.buildMonkeyFish("Bob");
monkey_fish->go();
}
I still have global objects.
Even if the MonkeyFishFactory itself created the GlobalObjects internally (so they are now inside the MonkeyFishFactory instead of true globals), it seems like the MonkeyFishFactory itself still needs to be a global object so that I can access it anytime I want to create a MonkeyFish.
Isn't the Factory pattern the same thing as global state in this case?
(I'm currently operating under the assumption that global state is a Bad Thing, and eliminating it is a Good Thing.)
Are you confusing concepts here?
The Factory pattern is usually applied when you are returning an instance of a concrete class that hides behind an abstract interface. The idea is that the caller will see just the interface and doesn't even have to know what the concrete type of the object is. It is all about creating an object instance based on parameters and decoupling the logic associated with deciding what object to create from the user creating the object.
What you are describing is a mixture of Singleton (or MonoState) and Factory. Your Factory has state so it cannot be made static. In this case, you will need to apply something like the Singleton pattern to control the creation of a single Factory instance with the appropriate globals hidden within it:
class IMonkeyFish {
public:
virtual ~IMonkeyFish() = 0;
virtual void go() = 0;
};
class Factory {
public:
static Factory& instance();
IMonkeyFish* createMonkeyFish();
protected:
Factory(GlobalObjectA& a, GlobalObjectB& b, GlobalObjectC& c);
private:
static Factory *theInstance;
GlobalObjectA& instanceOfA;
GlobalObjectB& instanceOfB;
GlobalObjectC& instanceOfC;
};
Factory& factory = Factory::instance();
IMonkeyFish* fishie = factory.createMonkeyFish();
fishie->go();
The Singleton pattern governs the creation of the factory instance. The Factory pattern hides the details surrounding the creation of objects that implement the IMonkeyFish interface. The Good Thing (TM) is the hiding of the global state and decoupling of the MonkeyFish concrete details from creating an instance.
The usage or correctness of using the Singleton stuff is a whole other issue though. There are probably a bunch of threads floating around about that as well.
Global state is not in-and-of-itself a Bad Thing. Public global state is a Bad Thing. The Factory pattern helps encapsulate global state, which is a Good Thing.
There are no global state in the Factory. It just creates objects.
Since it not any state in the factory. It's OK to be global.
You don't have to leave global objects. Monkey fish factory should create those GlobalOjectA|B|C on demand. Using switch or if inside method to determine which one.
You have encapsulated control over creation of objects in a factory. You want your instantiation details to be hidden away, not reproduced everywhere you need a new MonkeyFish. Think about testing, Single Responsibility, and the Law of Demeter. Why should your class that wants to use a MonkeyFish need to know anything about the work it takes to build one. What if you want to test MonkeyFish? How would you do it if you didn't have creation details encapsulated?
The job of a factory class is to instantiate an object and pass it back to the caller; not to pick which global instantiated object to use. So, your factory example is incorrect. It should be:
int main()
{
MonkeyFish * monkey_fish = MonkeyFishFactory::buildMonkeyFish("Bob");
monkey_fish->go();
}
Notice, no global objects, and MonkeyFishFactory is not instantiated.
I think you are thinking of the Singleton Pattern, not the Factory Pattern. In the singleton pattern you only have on instance of a class which basically makes it the equivalent of a global object except there is no global variable attached to it.
You should state your constraints and requirements if you want to get a good answer. The most important thing to get a good answer is knowing what question to ask.
In the code snippets you provided you have decided to use globals, but that has nothing to do with whether you use a Factory or not. If you use a factory that still depends on those globals, then you just have another piece of code to pile up with the rest.
Try to state clearly what you are trying to achieve and you will probably get a better answer.