Reputation: 658
I am having an issue designing a software. I have a very big object(BO), let's say a map of dynamic arrays, that I need to access across various classes. Each time a class uses BO, it adds new data to it, or uses some of the data in BO to do computation.
As a newbie, I am lost on how to design such an object in C++ so that my code design and architecture is good. Making a global variable is not efficient enough, researched on Singleton but found out the rule is you can only access the object, not change it.
Anyone can point me in the right direction? what design pattern should I follow that is the most efficient and scalable?
Thanks
Based on the answers here, is the following a correct design- it's psudo!
Class BigObject {
private static BigObject instance = null;
private map;
private BigObject() { }
public static BigObject getInstance() {
if (instance == null) {
instance = new BigObject();
}
return instance;
}
public getArray(string key) {
return map[key];
}
public setBigObject(string key, Array value) {
map.insert(key, value);
}
Upvotes: 2
Views: 313
Reputation: 1
"but found out the rule is you can only access the object, not change it."
You probably misunderstood something there?
The only purpose of a singleton is to guarantee to have a single instance of a class. You can still change its state as is permitted by its class member functions.
Regarding the singleton implementation you have posted in your updated question you should improve it to be thread safe (following Scott Meyer's Singleton):
class BigObject {
std::map<std::string,Array> map;
BigObject() { }
public:
static BigObject& getInstance() {
static BigObject instance;
return instance;
}
const Array& getArray(std::string key) const {
return map[key];
}
void setBigObject(string key, Array value) {
map.insert(key, value);
}
};
But as Singleton tightly couples your client code to the singleton class, you probably should declare an interface for your BigObject
, take references in the classes that need to have access, and pass an instance from construction:
struct IBigObject {
virtual void doCostlyCalculations() = 0;
virtual void updateData(std::vector<int> record) = 0;
virtual ~IBigObject() {}
};
class BigObject : public IBigObject {
virtual void doCostlyCalculations() {
// Implementation ...
}
virtual void updateData(std::vector<int> record) {
// Implementation ...
}
};
class ClientA {
IBigObject& bo_;
public:
ClientA(IBigObject& bo) : bo_(bo) {}
}
class ClientB {
IBigObject& bo_;
public:
ClientA(IBigObject& bo) : bo_(bo) {}
}
int main() {
BigObject bo;
ClientA ca(bo);
ClientB cb(bo);
// ...
};
Upvotes: 6