///The Whys and Why Nots of Java Accessors

The Whys and Why Nots of Java Accessors

When to use them, when to avoid them

This article explores the reasons you would want to use accessors, as well as the disadvantages to using them. This article is modified from Chapter 8 of The Object Primer 2nd Edition.

Accessors (member functions that directly manipulate the value of fields) were introduced in "Accessors increase robustness of Java code." Accessors come in two flavors: setters, which modify the value of a field, and getters, which obtain its value. Accessors do add some overhead to your code, but it is trivial — especially when compared to other factors, such as questionable database designs. In this tip I address two fundamental issues: why should you use accessor methods and when shouldn’t you?

Why use accessors?

Accessors improve the maintainability of your classes and components in the following ways:

  • Providing single points of update. You have single points of update for each attribute, making it easier to modify and to test. In other words, your attributes are encapsulated.
  • Controlling access to attributes. You have complete control over how attributes are accessed and by whom.
  • Enabling lazy initialization of "expensive" attributes. Lazy initialization means the value of an attribute is initialized (set) when it is first accessed. The advantage of this approach is that you incur the expense of obtaining the value only when and if you need it. The main disadvantage of lazy initialization is that your code becomes more complex because you need to check to see if the attribute has been defined yet and, if not, obtain its value. Lazy initialization is typically used when an attribute is expensive to calculate or obtain (perhaps it is very large and would take significant time to transmit across the network) and when it is not always required each time the object is brought into memory.
  • Reducing coupling between a subclass and its superclasses. When subclasses access inherited attributes only through their corresponding accessor methods, it is possible to change the implementation of attributes in the superclass without affecting any of its subclasses. This effectively reduces coupling between them. Accessors reduce the risk of the fragile base class problem where changes in a superclass ripple throughout its subclasses.
  • Encapsulating changes to attributes. If the business rules pertaining to one or more attributes change, you can potentially modify your accessors to provide the same capability as before the change, making it easier for you to respond to the new business rules.
  • Mitigating the issue of name hiding. Although you should avoid name hiding (giving local variables the same names as attributes), the use of accessors to always access attributes means you can give local variables any name you want. You don’t need to worry about hiding attribute names because you never access them directly anyway.
  • Encapsulating validation logic. If you need to implement critical validation logic, such as ensuring that a deposit into a bank account is always positive, then a valid place to consider putting that logic is in the setter.
  • Encapsulating undo/redo logic. If your application needs to support undo/redo logic, having accessors in place greatly facilitates implementing this functionality.

An advanced use of getters is to obtain the values of constants. Unfortunately this technique is not very common in the Java programming world. What is common is the use of use static finals to implement "constant" values, an approach that goes against the object-oriented concept of information hiding. Encapsulating the value of constants in static getter methods instead gives you a significantly more robust solution. When those values change, or when they evolve from being a constant into a value that is calculated according to a defined set of business rules, you only need to update the value in the getter and not every line of code where the constant is used. Static fields aren’t ideal but are reasonably painless when the value of the constant isn’t likely to change — such as the values for the days of the week. However, when the constant represents a user-defined value, such as the minimum value that a mutual fund must contain, then you are at risk that this value could change and are therefore better served by implementing it as a static getter method.

When shouldn’t you use accessors?

The only time you might not want to use accessors is when execution time is of the utmost importance, but it is a rare case, indeed, that the increased coupling within your application justifies this action. In Concurrent Programming in Java (see Resources), Lea makes this case for minimizing the use of accessors: often the values of attributes in combination must be consistent and it isn’t wise to provide access to attributes singly. He is right, so don’t make all your accessors public! In this situation, I would implement a bulk setter method, a method that would update several attributes at once, validating their business values appropriately, and invoke private setter methods that update a single value. I think Lea has missed the point that you don’t need to make all accessor methods public, as I pointed out in "Java accessor visibility." As an aside, bulk setter methods are quite common for EJB 1.x development efforts to counteract the standard, and performance degrading, approach to persistence. In short, when the values of some attributes depend on one another, then you should introduce methods that do the "right thing" and make the appropriate accessor methods protected or private as needed.

Acknowledgement

Special thanks to Chris Roffler, Senior EJB Architect at Ronin International, for his insights into this tip.

Resources

  • Building Object Applications That Work: Your Step-By-Step Handbook for Developing Robust Systems with Object Technology by Scott W. Ambler. New York: Cambridge University Press, 1998.
  • Process Patterns — Building Large-Scale Systems Using Object Technology by Scott Ambler. New York: Cambridge University Press, 1998.
  • The Object Primer 2nd Edition by Scott W. Ambler. New York: Cambridge University Press, 2000.
  • The Unified Process Construction Phase by Scott W. Ambler and Larry L. Constantine. Gilroy, CA: R&D Books, 2000.
  • The Java Language Specification by James Gosling, Bill Joy, and Guy Steele. Reading, MA: Addison-Wesley Longman, Inc., 1996.
  • Advanced Java: Idioms, Pitfalls, Styles and Programming Tips by Chris Laffra. Upper Saddle River, NJ: Prentice Hall Inc., 1997.
  • Essential Java Style: Patterns for Implementation by Jeff Langr. Upper Saddle River, NJ: Prentice-Hall PTR, 1999.
  • Java 2 Performance and Idiom Guide: Guidelines for Java 2 Performance, Coding, and Testing by Craig Larman and Rhett Guthrie. Upper Saddle River, NJ: Prentice Hall Inc., 2000.
  • Concurrent Programming in Java: Design Principles and Patterns by Doug Lea
  • Object-Oriented Software Construction, Second Edition by Bertrand Meyer. Upper Saddle River, NJ: Prentice-Hall PTR, 1997.
  • The Elements of Java Style by Alan Vermeulen, Scott W. Ambler, Greg Bumgardner, Eldon Metz, Trevor Misfeldt, Jim Shur, and Patrick Thompson. New York: Cambridge University Press, 2000.
  • 2010-05-26T17:17:55+00:00 March 6th, 2003|Java|0 Comments

    About the Author:

    Scott W. Ambler is President of Ronin International, a consulting firm specializing in object-oriented software process mentoring, architectural modeling, and Enterprise JavaBeans (EJB) development. He has authored or co-authored several books about object-oriented development, including the recently released The Object Primer 2nd Edition, which covers, in detail, the subjects summarized in this article. He can be reached at scott.ambler@ronin-intl.com and at his Web site at www.ambysoft.com.

    Leave A Comment