What should be allowed inside getters and setters?

I got into an interesting internet argument about getter and setter methods and encapsulation. Someone said that all they should do is an assignment (setters) or a variable access (getters) to keep them “pure” and ensure encapsulation.

  • Am I right that this would completely defeat the purpose of having getters and setters in the first place and validation and other logic (without strange side-effects of course) should be allowed?
  • When should validation happen?
    • When setting the value, inside the setter (to protect the object from ever entering an invalid state – my opinion)
    • Before setting the value, outside the setter
    • Inside the object, before each time the value is used
  • Is a setter allowed to change the value (maybe convert a valid value to some canonical internal representation)?

6

I remember having a similar argument with my lecturer when learning C++ at university. I just couldn’t see the point of using getters and setters when I could make a variable public. I understand better now with years of experience and I’ve learned a better reason than simply saying “to maintain encapsulation”.

By defining the getters and setters, you will provide a consistent interface so that if you should wish to change your implementation, you’re less likely to break dependent code. This is especially important when you classes are exposed via an API and used in other apps or by 3rd parties. So what about the stuff that goes into the getter or setter?

Getters are generally better off implemented as a simple dumbed-down passthrough for access to a value because this makes their behaviour predictable. I say generally, because I’ve seen cases where getters have been used to access values manipulated by calculation or even by conditional code. Generally not so good if you are creating visual components for use at design time, but seemingly handy at run time. There’s no real difference however between this and using a simple method, except that when you use a method, you are generally more likely to name a method more appropriately so that the functionality of the “getter” is more apparent when reading the code.

Compare the following:

int aValue = MyClass.Value;

and

int aValue = MyClass.CalculateValue();

The second option makes it clear that the value is being calculated, whereas the first example tells you that you are simply returning a value without knowing anything about the value itself.

You could perhaps argue that the following would be clearer:

int aValue = MyClass.CalculatedValue;

The problem however is that you are assuming that the value has already been manipulated elsewhere. So in the case of a getter, while you may wish to assume that something else might be going on when you are returning a value, it is difficult to make such things clear in the context of a property, and property names should never contain verbs otherwise it makes it difficult to understand at a glance whether the name used should be decorated with parentheses when accessed.

Setters are a slightly different case however. It is entirely appropriate that a setter provide some additional processing in order to validate the data being submitted to a property, throwing an exception if setting a value would violate the defined boundaries of the property. The problem that some developers have with adding processing to setters however is that there is always a temptation to have the setter do a little more, such as perform a calculation or a manipulation of the data in some manner. This is where you can get side-effects that can in some cases be either unpredictable or undesirable.

In the case of setters I’m always apply a simple rule of thumb, which is to do as little as possible to the data. For example, I will usually allow either boundary testing, and rounding so that I can both raise exceptions if appropriate, or avoid unnecessary exceptions where they can be sensibly avoided. Floating point properties are a good example where you might wish to round excessive decimal places to avoid raising an exception, while still allowing in range values to be entered with a few additional decimal places.

If you apply some sort of manipulation of the setter input, you have the same problem as with the getter, that it is difficult to allow others to know what the setter is doing by simply naming it. For example:

MyClass.Value = 12345;

Does this tell you anything about what is going to happen to the value when it is given to the setter?

How about:

MyClass.RoundValueToNearestThousand(12345);

The second example tells you exactly what is going to happen to your data, while the first won’t let you know if you value is going to be arbitrarily modified. When reading code, the second example will be much clearer in it’s purpose and function.

Am I right that this would completely defeat the purpose of having
getters and setters in the first place and validation and other logic
(without strange side-effects of course) should be allowed?

Having getters and setters isn’t about encapsulation for the sake of “purity”, but about encapsulating in order to allow code to be easily refactored without risking a change to the class’s interface which would otherwise break the class’s compatibility with calling code. Validation is entirely appropriate in a setter, however there is a small risk is that a change to the validation could break compatibility with calling code if the calling code relies on the validation occurring in a particular way. This is a generally rare and relatively low-risk situation, but it should be noted for the sake of completeness.

When should validation happen?

Validation should happen within the context of the setter prior to actually setting the value. This ensures that if an exception is thrown, the state of your object won’t change and potentially invalidate its data. I generally find it better to delegate validation to a separate method which would be the first thing called within the setter, in order to keep the setter code relatively uncluttered.

Is a setter allowed to change the value (maybe convert a valid value
to some canonical internal representation)?

In very rare cases, maybe. In general, it is probably better not to. This is the sort of thing best left to another method.

10

If the getter/setter simply mirrors the value then there is no point in having them, or in making the value private. There is nothing wrong with making some member variables public if you have a good reason. If you are writing a 3d point class then having .x, .y ,.z public makes perfect sense.

As Ralph Waldo Emerson said, “A foolish consistency is the hobgoblin of little minds, adored by little statesmen and philosophers and the designers of Java.”

Getters/setters are useful where there may be side effects, where you need to update other internal variables, recalculate cached values and protect the class from invalid inputs.

The usual justification for them, that they hide the internal structure, is generally the least useful. eg. I have these points stored as 3 floats, I might decide to store them as strings in a remote database so I’ll make getters/setters to hide them, as if you could do that without having any other effect on the caller’s code.

9

Meyer’s Uniform Access Principle: “All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.” is the main reason behind the getters/setters, aka Properties.

If you decide to cache or lazily compute one field of a class then you can change this anytime if you have only exposed property accessors and not the concrete data.

Value objects, simple structures don’t need this abstraction but a fully fledged class does, in my opinion.

A common strategy for designing classes, which was introduced through the Eiffel language, is Command-Query Separation. The idea is that a method should either tell you something about the object or tell the object to do something, but not to do both.

This only relates to the public interface of the class, not the internal representation. Consider a data model object that’s backed by a row in the database. You could create the object without loading the data in, then the first time you call a getter it actually does the SELECT. That’s fine, you might be changing some internal details about how the object’s represented but you’re not changing how it appears to clients of that object. You should be able to call getters multiple times and still get the same results, even if they do different work to return those results.

Similarly a setter looks, contractually, like it just changes the state of an object. It might do that in some convoluted fashion—writing an UPDATE to a database, or passing the parameter on to some internal object. That’s fine, but doing something unrelated to setting the state would be surprising.

Meyer (the creator of Eiffel) also had things to say about validation. Essentially, whenever an object is quiescent it should be in a valid state. So just after the constructor has finished, before and after (but not necessarily during) every external method call, the object’s state should be consistent.

It’s interesting to note that in that language, the syntax for calling a procedure and for reading an exposed attribute both look the same. In other words, a caller can’t tell whether they’re using some method or working directly with an instance variable. It’s only in languages that don’t hide this implementation detail where the question even arises—if callers couldn’t tell, you could switch between a public ivar and accessors without leaking that change into client code.

Another acceptable thing to do is cloning.
In some cases, you need to make sure, that after someone gives your class eg. a list of something, he cannot change it inside your class (nor change the object in that list). Therefore you make deep copy of parameter in setter and return deep copy in getter.
(Using immutable types as parameters is annother option, but above is assuming it is not possible)
But don’t clone in accessors if it is not needed. Its easy to think (but not appropriately) about properies/getters and setters as constant cost operations, so this is performance landmine waiting for user of api.

There’s not always a 1-1 mapping between property accessors and the ivars that store the data.

For example, a view class might provide a center property even though there’s no ivar that stores the center of the view; setting center causes changes to other ivars, like origin or transform or whatever, but clients of the class don’t know or care how center is stored provided that it works correctly. What should not happen, though, is that setting center causes things to happen beyond whatever is necessary to save the new value, however that’s done.

The best part about setters and getters is that they make it easy to alter the rules of an API without changing the API. If you detect a bug, it’s much more likely that you can fix the bug in the library and not have every consumer update its code base.

I tend to believe that setters and getters are evil and should only be used in classes that are managed by a framework/container. A proper class design should not yield getters and setters.

Edit: a well-written article on this subject.

Edit2: public fields are a nonsense in an OOP approach; by saying that getters and setters are evil I do not mean that they should be replaced by public fields.

5

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật