I am considering using the Registry pattern in my application to store weak pointers to some of app's windows and panes. The general structure of the application is shown below.
The application has one MainFrame top level window with few child panes within it. There can be many of TabPane type based tabs. I need to reference the ParamsPane panel from all of my TabPane tabs, so I need a pointer to the ParamsPane object to be stored somewhere. There can be a plenty of options, but the most obvious ones are (1) to store the pointer within the Application singleton object or (2) to create a simple registry class. Something like:
class Registry {
public:
static MainApp* application;
static MainWindow* mainWindow;
};
Is this a good practice? What are the benefits and caveats of such an approach?
It depends on why you want to reference ParamsPane. I can think of two reasons and two different solutions.
You want to update data in ParamsPane because data in TabPane changed.
If this data is completely separatable from the view, what you should probably do is separate it. This means following the Model-View-Controller pattern. Both ParamsPane and TabPane instances can access the model separatly. So there is no direct reference between the two.
There is some strong link between the two, irrelevant of data.
If the previous mentioned point isn't relevant, and there is a really strong link between the two panels you could consider writing a specific TabPane class which stores a reference to a ParamsPane class.
I feel both these solutions are better than a Singleton or 'Registry' approach. Beware that I haven't heard of this pattern before, but I believe I understand its intent. More info on why global state objects (more specifically singletons) are a bad practice can be found here.
In terms of testability, it may not be a good idea to use the Registry Pattern. To repost from this article:
Unit testing is predicated on the assumption that you are testing small, discrete units of code that do not have dependencies. This requires that developers do everything they can to either remove dependencies or mock them in such a way that the dependencies are neutralized as contributors to the failure of the unit being tested. In PHP 5, objects are not copied when assigned; instead, their address in a hash table is copied. This means that if you retrieve an object from the registry, and then modify it, every subsequent retrieval from the registry will reflect that modification.
The reason this creates a significant issue is that it prevents you from testing a discrete unit of code. Now, instead of one thing being the variable in a test failure, there are two: the unit of code being tested and the object it retrieved from the registry. Any time there is more than one possibility for failure, the effectiveness of the unit testing is diminished.
Your Registry class and Singleton are OO-ways of global variables. Prefer to make the Params Pane in the MainFrame and to pass it as reference to the tab-panes.
Related
Assume there is a function that requires a configuration setting as an input, but this function is called several levels deep from the top-level 'main' function.
What's the best way, in terms of best programming practices, to pass this setting to the function?
One way is to just use a global variable and set that at the top level function and read it in the target function, but I assume that that is considered bad programming practice.
Another way is to pass the setting as an argument all the way from the top, through the several intermediate functions, all the way down to the final target function. This seems very tedious though and perhaps error-prone.
Are there other approaches?
You can use your language of choice for your answer, but FYI, I'm using C/C++, Perl, and Matlab.
I like singleton objects for configuration. It's a shared resource that should only ever have one instance. When you try to create a new object, you get the existing one. You don't worry about global variables or subroutine or method parameters. Simply get a new configuration object and use it as long as you need it.
There's an example in Gang of Four for C++.
Leave the procedural programming style with deep call stacks behind and the answer becomes a banality.
Remodel your program to take advantage of modern object-orientation. Perl roles make for flat hierarchies. A configuration is then just an attribute.
A system I work with uses a Publish-Subscribe (Observer Pattern) implementation to propagate settings/configuration changes to objects that need to know about them.
The object (Subscriber, or Observer in the original Gang of Four description) that needs to be notified of settings changes:
Inherits from Subscriber.
Attaches itself (subscribes) to the Publisher via the Publisher's Attach method.
Is notified by the Publisher whenever settings/configuration changes occur.
We use a variant that allows Subscribers to poll Publishers for settings/configuration data on demand.
Using the Publish-Subscribe pattern minimizes coupling between the object that manages the settings, and the objects that need them.
In matlab, I always have a script allParam.m, where I set all the parameters.
If a function needs one of those parameters, I just call the script, and it is set.
Imagine you have a large application project, the code is split into a range of subsystems implemented as classes derived from CBaseSubsystem.
Here already comes my first question:
Is it a good idea to organize subsystems as classes [derived from a base class]?
Then, you have your subsystem classes. Now, you will need create have instances of them somewhere. But where?
Is it a good idea to have every subsystem instance stored in a global variable, for example:
extern CEventSystem* g_EventSystem;
Where should the instances be actually created? All together in a main()-like function?
Or is it better to avoid global variables entirely and organize the instances in a CSubsystemManager class or the like?
Would using singleton classes be an appropriate approach?
Very similar to this. I'd avoid Singleton, because it is absolutely unnecessary here and brings about many other issues.
Create the instances in a main-like routine. If something needs a system, provide access to it through some means, be it a parameter passed directly to that something or a container that provides access to these systems (IE: CSubSystemManager). You likely don't need to go so far as to write CSubSystemManager.
Avoid global state, there's a reason it has a stigma.
If you need a way to access an instance of each subsystem, I would avoid using "extern" and instead go with a singleton that gives you access to an instance of CSubsystemManager. The manager itself can take care of instantiating and managing your subsystem objects.
If you want to talk theory rather than provide a concrete question then consider designing in terms of a combination of Factory and Singleton with the possibility of Strategy in subsystems which may implement a similar operation for a range of different object types.
The main subsystem Factory is itself a singleton whose purpose is I hope obvious. Use lazy evaluation to allow only required subsystem objects to be loaded as needed. You may want to consider providing each subsystem with a reference counting mechanism which will allow them to be dropped when no longer needed. Some subsystems may themselves be singletons and/or may also implement Strategy pattern to provide a particular service for a range of class types.
This service may be for example validation, rendering, serialisation etc.
The value judgement of whether it is a "good idea" to build your application in this way is not for me to say. I would rather let older wisdom speak to that.
My solution would create a combo of a singleton Registry, AbstractFactory and Factory.
//in base module
class ISubsystem{} //an interface for a subsystem
//in module code
Registry::instance()->registerFactory("subsystem1",new Subsystem1Factory());
//in user code
IFactory* factory = Registry::instance()->getFactory("subsystem1");
ISubsystem* subsystem = factory->createObject(...); //you can implement whatever policy in factory impl. (like singleton etc.)
I have to write a bunch of DTOs (Data Transfer Objects) - their sole purpose is to transfer data between client app(s) and the server app, so they have a bunch of properties, a serialize function and a deserialize function.
When I've seen DTOs they often have getters and setters, but is their any point for these types of class? I did wonder if I'd ever put validation or do calculations in the methods, but I'm thinking probably not as that seems to go beyond the scope of their purpose.
At the server end, the business layer deals with logic, and in the client the DTOs will just be used in view models (and to send data to the server).
Assuming I'm going about all of this correctly, what do people think?
Thanks!
EDIT: AND if so, would their be any issue with putting the get / set implementation in the class definition? Saves repeating everything in the cpp file...
If you have a class whose explicit purpose is just to store it's member variables in one place, you may as well just make them all public.
The object would likely not require destructor (you only need a destructor if you need to cleanup resources, e.g. pointers, but if you're serializing a pointer, you're just asking for trouble). It's probably nice to have some syntax sugars constructors, but nothing really necessary.
If the data is just a Plain Old Data (POD) object for carrying data, then it's a candidate for being a struct (fully public class).
However, depending on your design, you might want to consider adding some behavior, e.g. an .action() method, that knows how to integrate the data it is carrying to your actual Model object; as opposed to having the actual Model integrating those changes itself. In effect, the DTO can be considered part of the Controller (input) instead of part of Model (data).
In any case, in any language, a getter/setter is a sign of poor encapsulation. It is not OOP to have a getter/setter for each instance fields. Objects should be Rich, not Anemic. If you really want an Anemic Object, then skip the getter/setter and go directly to POD full-public struct; there is almost no benefit of using getter/setter over fully public struct, except that it complicates code so it might give you a higher rating if your workplace uses lines of code as a productivity metric.
I have previously asked about the proper way of accessing member variables present in the project. In the project, I have CWinapp-derived class, CMainFrm class, a list of different view classes. However, currently, I have instances of different user-defined classes instantiated in the CWinApp-derived class, while the rest of the classes use a pointer obtained from AfxGetApp() function, and then access the different user-defined classes. I was told by some community members on the MFC newsgroup that this is a very bad design (i.e. the parent should not know anything about an app-class, view class, or document class). However, I'm not sure how otherwise I can access various user-defined classes without using this design. It would be great to hear some suggestions as I'm not familiar enough with MFC to come up with proper search terms.
"(i.e. the parent should not know anything about an app-class, view class, or document class)"
I'm not sure I understand this sentence, what do you mean with 'parent' here?
Anyway, in my opinion, the design you describe isn't really a problem. It's a trade off: do you either pass these classes to all functions that need them, complicating their use and API, or do you store them as a sort of global variables like you're doing? It depends on the data that is accessed, and how often. Data that is needed in many places can just as well be 'global'.
There are multiple ways of making data 'global': make it a member of CWinApp (that is, your CWinApp-derived class), or of CMainFrame, or do you make an actual 'global variable', or do you make a singleton, ...
The problem with global variables is that it becomes hard to figure out who accesses it when and from where. If you data as a member of CWinApp, you can access it through an accessor function and trace access from there (through log messages, break point, ...) This, in my opinion, mitigates most of the problems associated with global variables. What I usually do nowadays is use a Loki singleton.
The reason that is stated in your post for not making data a member of CWinApp, as a decoupling issue, is (in the context that you've presented it) a bit strange imo. If certain classes need access, they'll need to know of those data structures anyway, and their storage location is irrelevant. Maybe it's just because I don't know about the specifics of your design.
I am writing a perl script to parse a mysql database schema and create C++ classes when necessary. My question is a pretty easy one, but us something I haven't really done before and don't know common practice. Any object of any of classes created will need to have "get" methods to populate this information. So my questions are twofold:
Does it make sense to call all of the get methods in the constructor so that the object has data right away? Some classes will have a lot of them, so as needed might make sense too. I have two constrcutors now. One that populates the data and one that does not.
Should I also have a another "get" method that retrieves the object's copy of the data rather that the db copy.
I could go both ways on #1 and am leaning towards yes on #2. Any advice, pointers would be much appreciated.
Ususally, the most costly part of an application is round trips to the database, so it would me much more efficient to populate all your data members from a single query than to do them one at a time, either on an as needed basis or from your constructor. Once you've paid for the round trip, you may as well get your money's worth.
Also, in general, your get* methods should be declared as const, meaning they don't change the underlying object, so having them go out to the database to populate the object would break that (which you could allow by making the member variables mutable, but that would basically defeat the purpose of const).
To break things down into concrete steps, I would recommend:
Have your constructor call a separate init() method that queries the database and populates your object's data members.
Declare your get* methods as const, and just have them return the data members.
First realize that you're re-inventing the wheel here. There are a number of decent object-relational mapping libraries for database access in just about every language. For C/C++ you might look at:
http://trac.butterfat.net/public/StactiveRecord
http://debea.net/trac
Ok, with that out of the way, you probably want to create a static method in your class called find or search which is a factory for constructing objects and selecting them from the database:
Artist MJ = Artist::Find("Michael Jackson");
MJ->set("relevant", "no");
MJ->save();
Note the save method which then takes the modified object and stores it back into the database. If you actually want to create a new record, then you'd use the new method which would instantiate an empty object:
Artist StackOverflow = Artist->new();
StackOverflow->set("relevant", "yes");
StackOverflow->save();
Note the set and get methods here just set and get the values from the object, not the database. To actually store elements in the database you'd need to use the static Find method or the object's save method.
there are existing tools that reverse db's into java (and probably other languages). consider using one of them and converting that to c++.
I would not recommend having your get methods go to the database at all, unless absolutely necessary for your particular problem. It makes for a lot more places something could go wrong, and probably a lot of unnecessary reads on your DB, and could inadvertently tie your objects to db-specific features, losing a lot of the benefits of a tiered architecture. As far as your domain model is concerned, the database does not exist.
edit - this is for #2 (obviously). For #1 I would say no, for many of the same reasons.
Another alternative would be to not automate creating the classes, and instead create separate classes that only contain the data members that individual executables are interested in, so that those classes only pull the necessary data.
Don't know how many tables we're talking about, though, so that may explode the scope of your project.