25
Thu, Apr
0 New Articles

Practical Java

Java
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

When creating a Java application, a developer must often strike a balance between conflicting requirements: You want your classes to follow standard object-oriented programming (OOP) guidelines; however, the resulting application must be fast and easy to maintain and must be completed on time. If you rigorously follow all OOP guidelines and make your classes bulletproof under any condition, you will have trouble meeting project deadlines (not to mention the performance problems). This article explores a few simple suggestions I have found helpful in striking a balance between OOP purity and application simplicity.

Public Fields Are Your Friends

Most of the time, you want your class fields (variables) to be private or protected. The idea is to provide the mutator methods SET and GET for each field that should be accessible by other classes. You should make sure that the mutators create copies of the fields in question if they are not primitive data types. For example, a method to change the value of a private integer field called creditLimit would look like the setCreditLimit method shown in Figure
1. Notice that creditLimit object variable is assigned the value of the integer parameter newLimit. This technique prevents access to the private fields of your class without going through the SET/GET methods.

By encapsulating access to the attributes of a class with GET and SET methods you’ll gain other benefits such as the ability to validate the data with sanity checks for such things as making sure the order date isn’t later than the invoice date. The SET/GET methods are also a requirement if you want your class to be a JavaBean (see the Bean discussion later in this article).

So far, we’re in safe OOP territory. Coding all of these SET/GET methods is a lot of work, though, and can add many lines of code to your class. So is this all really necessary? Is there a valid reason for breaking OOP encapsulation rules, making a field public, and allowing other classes to manipulate the field directly? The answer is yes (to improve performance and to simplify the use of immutable objects). Consider the case for using transfer objects. The primary purpose of a transfer object is to convey information from one object to another. An event is a good example of a transfer object. I use custom events to let an object know that something has happened and to provide supporting


information. Figure 2 is an example of a simple class that encapsulates information about a custom event.

I use the TimeSyncEvent class in my TimeSync utility (see my article “Keeping Time with the AS/400” on page 43 for more information about TimeSync) to let registered “listeners” (i.e., associated Java routines) know that an event has occurred, specifically that an AS/400’s system values for QDATE and QTIME have just been modified. The associated routines asynchronously receive the TimeSyncEvent object, at which time they react to the information contained in the object.

The syncTime field inside the event object tells you the new system time on the AS/400. Notice in Figure 3 that the syncTime field is public. A registered listener might process the event in its actionPerformed method. Does the code in Figure 3 violate OOP principles? Sure, it has violated the most basic of encapsulation rules: Never allow external access to the fields of a class. The TimeSyncEvent class, because its timeSync field is public, allows other classes to directly access the syncTime field directly without the use of a GET method. Is this OK? In the case of transfer objects, I think this kind of simplification is perfectly acceptable, because they aren’t going to break anything by changing the value of the timeSync field; the TimeSyncEvent class is purely informational.

Avoid Method Nesting

Method nesting is a term I give to classes that take a linear process and break it up into a series of methods that must be called in sequence. For example, method A calls method B, which in turn calls method C. This kind of coding often results from the viewpoint that methods ought to be “small.” In fact, I have spoken to programmers who use the amount of source they can see on one or two screens as the rule of thumb when deciding to break up a “large” method into a series of “smaller” methods. Recently, a colleague took one of my methods that had nested for loops and broke it into three or four smaller methods. Each of the new methods basically represented one level of the four loops. Did the final result do anything to make the code more readable or maintainable? Since I use IBM’s VisualAge for Java (VAJ), the answer for me is no. Now I have to jump from one method to another (not easy, since VAJ orders methods alphabetically) to follow the logic of what was once a simple process.

So when should you consider breaking a method up into several smaller methods? The guidelines in Java are the same as those you would use in a well-written RPG subroutine. A Java method (just like a good RPG subroutine) should do two things. The first thing the method should do is narrowly focus on a single task. A getOrderHeader method, for example, should not also try to build some type of display and present that information to the user. You would expect getOrderHeader to perhaps access the database, retrieve a specific order header record, and return the result as a vector or maybe a java.sql.ResultSet.

The second thing a Java method should do is consolidate repeated code. If you have several methods with nearly identical sections of code, consider putting the repeating sections in a single, separate method. This will make your code more readable and likely reduce errors. (Programmer’s Axiom No. 14: If you are doing the same thing in two separate places, it is wrong in one.) For example, if you have two separate places where you validate an account number, move the code to a separate method called boolean isAccountValid(int accountNumber). Now if someone later wants to change the rules that make an account number valid, they can go to one place to modify the code.

Readability is important. A method that takes 15 pages to print is hard to comprehend and, hence, hard to maintain. Of course, such a long method probably isn’t following the guidelines listed above, either.

Resist Excessive Subclassing


There is a tendency in Java (especially when making enhancements to someone else’s code) to overuse the features of OOP inheritance by arbitrarily designing subclasses. The idea is that you have less chance of messing up someone else who is using the existing class if you just make a new subclass. Whenever you’re tempted to create a new subclass, ask yourself whether the new functionality or fields really constitute a unique case or whether they can be folded into the existing class structure as a new method call or property. If your class hierarchy never branches, watch out: You may be guilty of unnecessary subclassing. You probably could collapse several subclasses and superclasses without a loss of clarity or functionality.

You already may have seen the equivalent of excessive subclassing in the world of RPG. Perhaps you brought in a consultant to add a new menu option to your green-screen application. If the consultant made a copy of an existing program, changed a couple of lines, and added the menu option, you are a victim of the same bad practice. To lend a little more credence to my suggestion to reduce excessive subclassing, consider the following quote from Java Report (July 2000): “Then there are the people who go, ‘Ooooh, objects! They’re cool! Let’s make gazillions of them!’ Actually, that feels like almost a fault of the educational system, because if you look what lots of kids fresh out of school have been taught, it’s, ‘Objects are good, define lots of them!’ So you get programs with zillions of little adapters, with methods that are one or two lines long, and you start profiling them and they’re spending all of their time doing method dispatching.’” And who was it that said that? Gary Gosling—the creator of Java.

To Bean or Not to Bean...

JavaBeans are great. Visual tools—like IBM’s Visual Composition Editor (VCE), a feature of VAJ—flourish because of JavaBeans. A set of well-written JavaBeans can help you construct much of an application quickly, much like assembling Legos. In fact, JavaBeans are so useful that some programmers feel that all classes should be JavaBeans. At its core, a JavaBean is simply a Java class that follows strict naming conventions for methods. Private fields must be accessed by the SET/GET methods. For example, if you want to allow someone to access a private field named fileName, you must provide methods like setFileName or getFileName. Tools like IBM’s VCE would then automatically recognize that your class has a property called filename. Most such tools also require you to add implements java.io.Serializable to your class definition so the tool can store your class on disk.

Sounds easy, and it is to a certain point. When a class is packaged as a JavaBean, however, there is an expectation of a certain amount of robustness. You, the programmer, must assume that other programmers will use your new Bean in ways that you never anticipated. You may need to provide many new events, just in case someone wants them someday. Since you can’t be sure of the context of your JavaBean’s use, you must add code to make sure that all method parameters are carefully validated. Robustness is a nice characteristic for a class, but that robustness comes at a cost: You will have to decide where to draw the line between having the robustness and reusability of a class and getting your project finished on schedule.

Following the general naming conventions for Bean methods is a good idea, but don’t expect your classes to behave appropriately in all situations with any kind of input. In other words, it is OK to write a class with a given environment in mind (a specific problem and data domain, in OOP terms). Doing so does not make you a bad programmer; just keep the intended user of your classes in mind.

Practically Done

Set some Java coding standards. As a start, you can download one of the many Java style guides from the Internet (start with java.sun.com). Be consistent: If you are going to bend some of the OOP rules, at least do it the same way every time. Always consider the


intended environment and who will likely be maintaining your classes. It is hard to go wrong if you always try to make your classes easy for someone else to later enhance.

Learn OOP principles. Take a class (no pun intended) or read a book that will introduce you to OOP, such as Object-Oriented Technology: A Manager’s Guide (Second Edition). You must know the rules before you can make an informed decision to deviate from those rules. Remember, learning Java syntax is not the same thing as knowing OOP design principles.

REFERENCES AND RELATED MATERIALS

• Object-Oriented Technology: A Manager’s Guide (Second Edition). David A. Taylor, Ph.D. Reading, Massachusetts: Addison-Wesley Publication Co., 1998

public void setCreditLimit(int newLimit)

throws CreditLimitException
{

if (newLimit > CORP_CREDIT_LIMIT)

{

throw new CreditLimitException();

}

creditLimit = newLimit;
}

Figure 1: Basic OOP encapsulation techniques make class fields private and provide GET and SET methods for retrieving and modifying the values of a field.

public class TimeSyncEvent extends ActionEvent
{

//kind of events supported

public static final int SYNC = AWTEvent.RESERVED_ID_MAX + 5556;

public GregorianCalendar syncTime = null;

public TimeSyncEvent(Object source, int id, String command)

{

super(source, id, command);

}

}

public void actionPerformed(ActionEvent evt)
{

if(evt instanceof TimeSyncEvent)

{

try

{

String dateTimestr = dfmt.format(
((TimeSyncEvent)evt).syncTime.getTime());

//update a screen or do something useful here


Figure 2: The TimeSyncEvent class breaks encapsulation rules by making the syncTime field public.

}

catch(Exception e) {}

}

}

Figure 3: The actionPerformed routine has direct access to the syncTime field but can’t break anything.


BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: