Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

package-private and protected access

 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34401
346
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the junit and privates thread, J. B. Rainsberger wrote:
I never use the package-level or protected access modifiers. I just find that I never need those levels of protection. To me, part of a class is either open or closed. Various degrees of "open" serve only to complicate my life, and my life is complicated enough.

I'm curious what others thingk of the various degrees of openness.

Personally, I find package-level and protected access to be useful. Especially for reusable components. I'm curious what others think.
 
Warren Dew
blacksmith
Ranch Hand
Posts: 1332
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think protected access is essential for properly designed inheritance trees. Otherwise, private implementation details common to multiple subclasses would have to be written and maintained separately for each subclass.

I don't like package access - or rather, I don't like the fact that protected functions can be accessed by classes not in the inheritance hierarchy just because they happen to be in the same package. I think I'd rather do without package access at all. If you had to declare package and protected access separately, with the default being private, that would be okay.

While package access to package level functions can be somewhat useful for "white box" testing of complex classes, it would probably be better to decompose those classes into simpler classes anyway.

I'm curious, though - what do you use package access for? I'm wondering if there's a separate, less object oriented programming style - perhaps whatever Ada was designed for - that would be oriented around packages instead.

Edit: I see in the other thread that you also use package access for testing only ... now I'm curious what other uses your coworkers have found for them?

[ August 12, 2004: Message edited by: Warren Dew ]
[ August 13, 2004: Message edited by: Warren Dew ]
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with Warren - I use private for implementation details, protected for reuse inside inheritance trees and public for everything else. I virtually never use package scope access.
 
Joyce Lee
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For subclassing, which access modifier would you prefer for instance variables: protected or private? If using private, the subclasses will have to use getter/setter to retrieve/modify the values. Martin Fowler has an article on this issue. What's your opinion?

As for the instance methods, if the subclasses require to access the methods in base class, I will use either public or protected depending on the scope.

Joyce
[ August 13, 2004: Message edited by: Joyce Lee ]
 
Warren Dew
blacksmith
Ranch Hand
Posts: 1332
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I never use protected data - only protected methods.

The primary value of the protected scope is to permit reuse of code between subclasses - one of the few cases where reuse of code is actually common. The point of code reuse is to allow changes to be made cleanly in one place, rather than having to change it every place it is used.

If you expose data as well as functions, you can no longer change the code for that data in the protected scope without checking and perhaps changing every subclass which might use that data. This defeats the whole point of code reuse - that is, of putting that material in the protected scope in the first place.

Getters and setters in the protected scope are okay by me, as they permit reuse of data while allowing changes in the underlying data implementation without having to change subclass code. For example, if after the product was working, I wanted to improve its speed, I might want to cache a calculated value. The cached value would have to change when the inputs to the calculation changed. If I had used a mutator (setter) to change one of those inputs, I could easily modify that mutator to also recalculate the cached value, or at least mark it as stale. If I had been accessing the input directly, I'd have to check and change all the subclass code - some of which I might not have access to.

I'll go read Fowler's article now, but I doubt he'd be able to change my mind.

Edit: okay, I've identified where Fowler goes wrong when he tries to please both sides. He goes wrong when he says, "I'm using the subclasses to provide polymorphic behavior, not to provide modularity." If he really were not using the subclasses to provide modularity, he would cut and paste the duplicated fields into the subclasses' private scope, rather than reusing them from the protected scope. In Java, if you don't want modularity, you can get polymorphism just fine by having an inheritance tree of interfaces rather than inheriting classes, and interfaces don't have protected scopes. Simply by using the protected scope, one is using inheritance for modularity as well as for polymorphism.

I'm interested in Ilya's answer. I think an argument might be made that with modern tools in an XP environment, modularity and code reuse is not as important as it once was. On the other hand, I don't think protected accessors and mutators violate Ilya's rule that objects should tell each other what to do, rather than getting stuff from each other - the protected scope isn't usually for communicating with other objects, it's for communication within the object.
[ August 13, 2004: Message edited by: Warren Dew ]
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34401
346
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All: thanks for responding. I feel better that you guys do use protected (and private) methods too.

Joyce,
I agree with Warren. I would never make data protected. I will make it package level, but only for testing. (and that assumes that everyone will respect the honor system and not access the data in real code.

Warren,
I don't like the fact that protected functions can be accessed by classes not in the inheritance hierarchy just because they happen to be in the same class.

That I agree with.
I'm curious, though - what do you use package access for? I'm wondering if there's a separate, less object oriented programming style - perhaps whatever Ada was designed for - that would be oriented around packages instead.

Edit: I see in the other thread that you also use package access for testing only ... now I'm curious what other uses your coworkers have found for them?

My coworkers are people on other teams that develop reusable components to be shared by the department. They make helper classes/methods package access and only expose the public API with public access. I guess the idea is that callers can physically only call the methods intended to be public.
 
Joyce Lee
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the input.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Warren Dew:
I think an argument might be made that with modern tools in an XP environment, modularity and code reuse is not as important as it once was.


Quite to the contrary - modularity and code reuse is one of the main tools to keep the code flexible. XP even has a Once And Only Once rule - no code or even logic duplication allowed.

On the other hand, I don't think protected accessors and mutators violate Ilya's rule that objects should tell each other what to do, rather than getting stuff from each other - the protected scope isn't usually for communicating with other objects, it's for communication within the object.


The intent of the rule is to reduce implementation dependencies between classes, so that changes to one class need minimal rework in other classes. I'd think that it is also important for inheritance relationships, though perhaps sometimes a little bit less critical.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic