Question about Encapsulation (Book: HF OOA&D )
i'm reading this book (Head First Object Oriented Design & Analysis). In chapter 5 there is a suggestion which i would like to have some other toughts about it. The book says:
"When you have a set of properties that vary across your objects, use a collection, like a Map to store those proeprties dynamically."
and further more, some explaination why to do it:
"You'll remove lots of methods from your classes, and avoid having to change your code when new properties are added to your app".
I do understand the advantage of this approach but isn't there a downsize as well? I mean if i use a map to store those informations (in the example it was a String to Enum map) and provide a getProperty(String) method to access, the caller of this method actually has to know which Strings are allowed. I don't like this somehow. I mean of course you can argue that it could be stated in the javadoc which input is allowed.
Is this really the way to deal with this kind of problem are there any alternatives? I understand that doing this with inheritence is not good because of the bulk of subclasses and开发者_JS百科 those subclasses would not override anything just add new properties which really isnt that good in my opinon.
I personally think that using a Map
instead of actual fields is a terrible idea. I had the misfortune to work with systems that employed this (anti)pattern extensively and it was a nightmare to maintain.
I see absolutely no reason to use maps for "future proofing", the argument that you can avoid having to add new methods is laughable, especially when you consider that adding a new field takes about 20 keystrokes, adding getters and setters for it another 3-4 mouse clicks. What you gain is nothing and what you lose is type safety and compile time checking, the ability to control and monitor what is being set and when, not to mention the fact that you break the principle of encapsulation.
It should also be noted that the development of the Java language itself has been moving towards more and more compile time checking, enums and generics being the most obvious examples of this direction. To throw it all away is even worse than it was in the 1.3-1.4 era
Maps should only be used when something is truly dynamic, i.e. there's no way the list of keys can be known at compile time.
You can implement your getProperty
method to accept an enum
value as the key. This would provide an easy way to show the user which keys are valid, and you wouldn't even have to modify the original enum
when you wanted to add more since you can extend the enum
. Granted, it might just be easier to modify the original enum
as it is kind of confusing to have an enum
inheritance hierarchy.
Yes, you'd have to know the keys to retrieve the data. No, this wouldn't cause any fundamental change; if you used a class hierarchy, you'd need to know the names of the classes and methods to call.
Note that you can make some use of items in a map without knowing the name up-front -- you can iterate through the map and (for example) show values to the user, allow modification, and let them apply particular keys to particular settings.
I'm not saying this is necessarily a good idea, but it can be done whether it's a good idea or not.
精彩评论