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

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.

Related

Should I use static classes in an ECS?

Hey I am currently working on a small entity component system where there are classes like EntityManager, ComponentManager and SystemManager that are only instantiated once and heavily communicate with each other.
I created a class world which owns all the managers and acts as the center for all communication between the managers. Making all the Managers static would make a lot of things much easier, more understandable and I wouldn't even need the world class.
I know though that static classes (I know "static classes" don't exist but I mean classes with only static members) act as if they were global and global variables are Bad®.
So I wonder what is recommended to do in this case
Thanks for your answers
Che
Edit:
The World class looks like this:
class World
{
public:
EntityManager* entityManager;
ComponentManager<PositionComponent>* componentManager;
MovementSystem* movementSystem;
Entity e;
public:
World(sf::RenderWindow& window);
void update();
};
To communicate each Manager needs a pointer to the world to access the other managers. Like this world->entityManager->getEntitys()
(I suggest that the project is a game or something close to it)
I don't suggest you to make all members static. The main problem with it that you're loosing control on object's lifetime. You can't destroy and create new object at runtime easily because there is no object. For example, if you want to change a manager at runtime you'll have to implement cleanup code manually. In case of C++ objects C++ helps you with errors/warnings, default values and class members by value.
There are few popular ways to implement and use managers in gamedev:
Use Singleton pattern. In this case class have one static method that returns link to non-static object.
Pass dependencies that method requires during the method call manually.
Singleton pattern, I think, is the best way in terms of price-quality ratio for you. Despite on all criticism of this pattern it does its job well (most of game projects I saw used Singleton approach to implement manager classes).
There is an important thing I want to suggest you about this pattern. Don't use default implementation of Singleton pattern. Create methods for creating and destroying object instead of hiding it inside of getter. Here's simple example of glue code for a manager:
class Manager {
private:
static Manager* ms_manager;
public:
static void CreateManager() { ms_manager = new Manager(); }
static void DestroyManager() { delete ms_manager; }
static Manager* GetInstance() { return ms_manager; }
};
Usage is:
Manager::GetInstance()->SomeMethod();
Passing dependencies approach has its own advantages. It may sounds too difficult to pass everything in every Update method but it's not. You can create context class, set all dependencies there and pass it to every method that needs it. It's almost like your World class but it must be structure with minimum of code and no dependencies. Don't store there any game objects by value (only primitives, geometry vectors and stuff like this). It may be something like this:
struct Context {
EntityManager* entityManager;
ComponentManager<PositionComponent>* componentManager;
MovementSystem* movementSystem;
Entity* rootEntity;
};
Usage is:
GameObject::Update(Context& context) { context.entityManager->SomeMethod(); }
The point of this approach that you can tune context for some objects at runtime. For example, if you have LODs you can save in context current LOD level and change it at runtime for some objects depends on distance to the camera.

C++ software design options, class relationships

Problem:
I have totally separate software managers (software entities), for example CCarManager, CTruckManager etc.. At some point I am creating new objects for example CCar. CCar must have relationships with various separate managers, for example, with CResourceManager, CTruckManager. What is the best way to link CCar with these managers?
Solutions:
Have global software managers (Singleton or extern in header file)
[Don't like globals]
Use one global point and pass it to other obects e.g CCar(CApplication), CApplication->TrukManager(), CApplication->CarManager()...
[Doesn't seem nice, but can pass one pointer]
Pass to CCar(CCarManager *pCarManager, CTruckManager *pTruckManager....)
[Hard to extend]
Use Observer pattern e.g. CCar.Attach(CCarManager), CCar.Attach(CTruckManager);
[Easy to extend, but main focus become for dealing method calls, what parts are responsible for what etc., also lot of check's]
Factory.
class CCarFactory(CCarManager *pMngr)
{
CCar *CreateCar()
{
return CCar(m_pCarManager);
}
}
what are the other ways?
You can pass a reference to CResourceManager, CTruckManager, etc. in CCar's constructor.
CCar(const CResourceManager& resourceMgr, const CTruckManager& truckMgr):
_resourceMgr(resourceMgr), _truckMgr(truckMgr) {
//relevant construtor code here
}
This way it's easy to test with mock implementations as well. It's hard to say without knowing what the 'Manager classes do.
IMHO, classes whose names end in 'Manager' are often either poorly named (which I've done more times than I can count), or poorly designed.
If the only reason you won't use the Singleton pattern is because you don't like it, I think you might want to reconsider your approach.
Singletons are a perfect pattern for what you're trying to acheive here. You have management classes that should only have one instance and require access from many other classes.
Its hard to say without some more specifications... If CCar requires special access to the manager methods (like internal variables/methods) or vice-versa, you can declare in CCar managers as friend, or CCar as friend in those manager classes.
simple example, mind the poor member names
class CCar
{
int I;
public:
friend class CManager;
CCar(int i): I(i) {}
};
class CManager
{
int D;
public:
CManager(int i, CCar& car): D(i)
{
car.I = 5; // modify CCar instance internal member
}
};
or vice versa if its the other way around.
If a CCar instance can have multiple CCarManagers, you could set up an array of pointers to 'link' those managers to an instance of CCar. Rather than having 3 different pManager arrays, having a Manager base class, and subclassing those managers to it, will let you store all references to managers in a single array.
class Manager // etc...
class CResourceManager : public Manager
// in CCar
std::vector<Manager*> _mgrs;
// or if heap allocated
std::vector<std::shared_ptr<Manager>> _mgrs; // assuming multiple CCars can reference same manager instance
Another method could be to have a struct/class that can hold all manager references for a particular instance.
struct MgrRefs
{
std::vector<CCarManager*> _pCarMgrs;
std::vector<CResourceManager*> _pResMgrs;
// etc....
};

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.

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

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.