开发者

Getters and Setters are bad OO design? [duplicate]

开发者 https://www.devze.com 2022-12-28 14:46 出处:网络
This question already has answers here: Why use getters and setters/accessors? (37 answers) Closed 7 years ago.
This question already has answers here: Why use getters and setters/accessors? (37 answers) Closed 7 years ago.

Getters and Setters are bad

Briefly reading over the above article I find that getters and setters are bad OO design and should be avoided as they go against Encapsulation and Data Hiding. As this is the case how can it be avoided when creating objects and how can one model objects to take this开发者_如何学Python into account.

In cases where a getter or setter is required what other alternatives can be used?

Thanks.


You have missed the point. The valid, important bit of that article is:

Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.

Java-style getter and setter proliferation are symptoms of ignoring this advice.


Getters or setters by themselves are not bad OO design.

What is bad is coding practice which includes a getter AND a setter for EVERY single member automatically, whether that getter/setter is needed or not (coupled with making members public which should not be public) - because this basically exposes class's implementation to outside world violating the information hiding/abstraction. Sometimes this is done automatically by IDE, which means such practice is significantly more widespread than it's hoped for.


Yes, getters and setters is an anti-pattern in OOP: http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html. In a nutshell, they don't fit into object-oriented paradigm because they encourage you to treat an object like a data structure. Which is a major misconception.

You may find more details in my book Elegant Objects.


I believe in including setters in the API only if they are really part of the class specification (i.e. its contract with the caller).

Any other data member related to inner representation should be hidden, and I see at least 2 major reasons for that:

1) If inner representation is exposed, design changes are more problematic in the future, and require API changes as well.

2) Exposing data members with setters/getters with no caution allows callers to ruin the class invariant very easily. Objects with inconsistent state can cause bugs which are very difficult to analyze.

Unfortunately there are some frameworks which encourage (sometimes require) adding setters/getters for everything.


Getters and setters are not bad by themselves. What is bad is the practice of making any field to be private and provide getters/setters for all of them no matter what.


The way I read it, the author argues that blindly putting getters and setters around fields is no better than just making the field public.

I believe that the author argues that getters and setters should be placed sparsely, and with care, because the idea of OO is that objects should limit their exposure to what is needed only.


I'll go a bit further and say only value types should have getters. Each value type should be immutable and come with a builder which is mutable and has setters.

If your value type has setters they should return a new instance after copying the other values.

Url.setAnchor(...)

Would return a new Url copying the host port etc but overwrite the anchor.

Your service type classes don't need setters ( set them in ctor) and definitely font need getters. Your Mailer should take the host/port/etc static stuff in it's ctor. If I wish to send an email then I cell it's send(), there is no reason why my code should need to know or want or require the host and other config values. That said it would make sense to create a MailServer class like the following // value type MsilServer{ String host int port String username Strung password // all come ruth getters } // factory Mailer create( MailServer)


Getters and setters are just methods. What do they do? They change a field into a property, and that's an important distinction.

A field is a bit of data, of state, in the object. A property is an externally observable characteristic, part of the contract of the object. Spraying the guts of an object all over the place, whether directly or through getters/setters, is always a bad idea. Poor design. But raising that to the point of saying that getters and setters are always bad? That's just some poor programmer without a sense of good taste claiming that a vague rule of thumb (which they didn't really understand in the first place) is a cast iron law.

Personally, I tend to go for trying to keep properties as being things that don't change unexpectedly underneath the clients' feet. (Clients of the class that is.) The only properties that I'll change dynamically are ones they can't write, and even then I'll try to avoid it. I feel that properties are in many ways values that control the behaviour of the instance which are set by the client, not arbitrary things under the control of the class. (That's what normal field is for...)


I suggest that you read the whole article carefully as it presents well thought out arguments and alternatives. The question itself is too open ended and the answers you get here will be just more opinions.


From the article:

When is an accessor okay? First, as I discussed earlier, it's okay for a method to return an object in terms of an interface that the object implements because that interface isolates you from changes to the implementing class. This sort of method (that returns an interface reference) is not really a "getter" in the sense of a method that just provides access to a field. If you change the provider's internal implementation, you just change the returned object's definition to accommodate the changes. You still protect the external code that uses the object through its interface.

In other words, use interfaces for both getter and setter methods when they are necessary that way you can maintain encapsulation. It is good practice in general to specify an interface for a return type or formal parameter.


There are other articles that say they are good design. But the answer is this: getXXX and setXXX are good or bad based on usage. these mathods do make a lot of things easier. So if some article says it's a bad design I think; it's just trying to be too hard on the idea.

One of the biggest usage of these methods are in a lot of framework and used as a reflection mechanism.

So don't completely avoid using these, rather... use it judiciously.

thanks Ayusman


Getters and Setters are bad OO design?

Only when used without thinking.

If you're to create a value-object to transport data, they're fine.

If you're creating a more important object then they shouldn't be there. Take a look at the ArrayList interface* for instance. You don't see Object[] getElementData() because that would break the encapsulation ( some one may temper the underlying array ) .

* Im referring to the public interface of the class ( the methods exposed by the class definition )


Getters/Setters are perfectly appropriate, in the right conditions. However, mass Get/Set is wrong.

However, I'm a tad confused. You tagged Java but the material isn't really particularly Java specific (only the examples). It's worth noting that in C++ (best done in 0x) many of these issues don't exist. If you wanted to change your interface from long to int, then between decltype, templates and auto this is easily achievable, which is why such constructs rock. Typedef works well too.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号