You Might As Well Make All Your Class Members Public

So recently some of us were discussing the fact that F# 3.0 is going to add a feature to make it more amenable to OO programmers.  F# 3.0 will add automatic “getters” and “setters” for members of a class. A small digression; I prefer the terms “inspector” and “mutator” because they seem more precise.

If it were up to me, though, most OO code would not use inspectors and mutators.  Why? Because the use of inspectors and mutators can defeat information hiding which is one of the principle benefits of object orientation. I’ll explain.  Let’s pretend we have a class C which contains a data member _m1.  This data member is an integer.  Something like this:

public class C
{
    private integer _m1;
    public integer m1 {
        get
        {
            return _m1;
        }
        set
        {
            _m1 = value;
        }
}

Now let’s say you need to reference m1 from other places in your code.  Everywhere you need to reference m1, you need to specify that m1 is an integer.  Every place in code that you need to set m1, you have to set an integer.  Now later on we may find that m1 needs to be a floating point.  Because I’ve got a public getter and setter, I now need to know about code which is referencing my class and I may need to modify that code.  This is violating the whole notion of encapsulation that we adopted OO to get.  And what if I’m sharing my code to other teams?  I might break their code and never even know about it.  At this point I might as well dispense with the private _m1 member because it’s not helping anything and in fact it’s just more work to maintain. I might as well not bother using private members.

Now some might say—well, what are you suggesting?  No inspectors or mutators?  I’d suggest we don’t need them as much as I’ve seen some OO programmers abuse this facility.  I’d also suggest another way to get back the encapsulation is to hide the actual type of the member behind something that indicates the significance of the value.   Like this example:

using EmployeeCount=System.Int32;

public class C
{
    private EmployeeCount _m1;
    public EmployeeCount m1 {
        get
        {
            return _m1;
        }
        set
        {
            _m1 = value;
        }
}

If I hide the actual type of _m1 behind EmployeeCount if I ever need to change the type of _m1 I only need to change it in one place and I don’t have to worry about code which accesses my class.  I’ve regained the encapsulation that I lost via opening part of the class’ internal details.