Mutators and Accessors (Setters and Getters) are, in my opinion, quite a debatable thing. Personally, I’ve always been in the school of thought that you don’t -need- them, but are needed for certain things like access control, security, etc. For example, if you have a Person object with an Age property, you would typically never want the age of that person to be less than 0. If you didn’t have a mutator, you would have check for Age being less than 0 and respond accordingly in all of the code that uses the Age variable. With a mutator, this requirement is essentially lifted because you can assume that anything that uses the class Person has to use the mutator to set the Age property (which means you can check for the “<0″ condition and respond when the Age property is set, rather than everytime you want to use the Age property in your code). This assumes also, that the Age property is private, of course, because if it wasn’t then having a mutator or accessor at all would be pretty useless.
I typically ignore mutators or accessors for a variety of things though. One big example is linked lists. I typically never make the Next and Previous fields in a linked list of objects private and I don’t make mutators/accessors for them. Two reasons for this is: Mutators and Accessors just complicate things unnecesarily and the second reason is that its just a habit, good or bad, from working with UnrealScript. If I remember correctly, UnrealScript just had Next and Prev or rather (NextPawn, NextController, etc.) but they were just variables. I think as far as security goes, its a bad idea, especially within UnrealScript where if you would have set NextPawn to something else while iterating through the list, you could destroy the entire rest of the list and bad things would happen then. Thankfully, UnrealScript had the “next…” property as constants, which basically meant that only the underlying engine could set them. Adding to the linked lists was done by the engine itself, and AFAIK couldn’t be done manually. This added the needed security I suppose. I’ve always liked how that worked though, because an Accessor here would be useless, although a mutator might be a good idea.
I bring this up now only because of what I’m working on at the moment. The GUI framework has given me an excellent opportunity to set the “standards” for the code base. At the beginning, I just wrote code and wrote more code until what I wanted was achieved, giving some thought to “the future” but it was mostly “code until it gets done, then I’ll come back and fix it.” I think now is that time. I read somewhere, either an article on the internet or somewhere in a textbook (actually, it could have been Beautiful Code), that an accessor and mutator where you passed around the actual underlying object was pretty useless and stupid. For example, if one of your classes is comprised of several other classes, having an accessor return one of those objects isn’t very “wonderful” for lack of better word.
The article goes on to say that instead of writing accessors that simply return an object, you should instead write a method that returns a useful part of that object. For example, instead of writing a method that returns a Person object, you would write a method that returns some useful information about that object, like that Persons Age, Name, etc. This encapsulates that Person object completely but still allows external communication about that person that is needed. This type of things isn’t directly applicable, but the security aspect is.
Because C++ doesn’t handle pointers the way I’d like them to (i.e. garbage collection) I’ve been forced to make some decisions. Some are stupid but needed, others really make sense in the long run. One such example is the Location property that appears in nearly all of my classes, game related or not. Before fixing the memory leaks, I passed around objects left and right, and set them accordingly. If I had a Vector Location that I needed to set to another Vector, the shorthand I would use was “A.Location = NewLocation”, rather than going through all the components and setting them individually or creating a mutator that did it for me. The result was a memory leak because the memory referenced by A.Location after the assignment turned into a dangling pointer. The quick solution to this was to add a method to my Vector class called Set that acted as a mutator. It simple took X, Y and Z coordinates and set the vectors components accordingly. This solved the memory leak. This is actually the way that its setup in the .Net framework (I… think) and even Java, except in .NET I think its really just hidden behind language features. In Java, at least with the GUI system, you have to use setLocation to either set the X,Y coordiates, or an overload method accepts a Point object which will override the private point field with the one you specify. You can’t actually access the Point variable, its encapsulated. This benefit becomes more apparent without a garbage collector.
One of the things I hate about my own code base is that the familiarity present in .NET and Java isn’t currently present in my engine. What I mean to say is the Location field, present in the majority of my codebase is usually called Location, but there are certain cases where I chose a different name. If I aim to move to a more “secure” type of framework, one complete with accessors and mutators where needed, then I accessors and mutators are a must for most of the variables however, I don’t want to copy and paste code here, there and everywhere. Thats the only thing that bothers me in the OOP world. If you want something from a completely unrelated class, you have to either make it part of the base class and derive all of your classes from that base or… well… typically “or” doesn’t exist. Interfaces are annoying, and don’t help in that situation either. They help with the whole naming and familiarity thing, but the functionality -has- to be implemented in a class that implements that interface. If I were to use Interfaces, I would still have to copy and paste the same implementation across a dozen classes. Multiple Inheritance in C++ might make my life easier though. I could create a few classes with some basic functionality (like a class with a Location field and accessors/setters to go with it) and have all base class roots inherit that. That might work.
The accessor problem is still there though. If I create an accessor that simply returns a component how useful is it? Given that the only use of the object is to specify a coordinate in 3D space there are a variety of things that can happen if I return the Location object. Because its pointer based, they can do all sorts of horrible things to it, like free the memory, which will destroy the Location object in whatever class it belongs to. If I return a new vector with the same values as the Location object, then I have a memory leak on my hands. I wonder if I can solve that problem without making my code 100% more complicated. I’m okay with establishing a rule book for myself to follow, but if someone else wants to addon to the engine ever, what stops them from breaking all the rules in the book?
Hmm.