22
Fri, Nov
1 New Articles

Java Journal: Design Patterns

Java
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times
One of the primary goals of object-oriented programming (OOP) has always been code reuse. The idea that you can write an object once and reapply it to many situations is very appealing. After working with objects and reusing them in several different systems, you begin to realize that not only do you reuse the objects themselves, but you also tend to reuse the relationships between the objects. It's that feeling of "I've done this before." The difference now is that it isn't just a matter of looking at one object, but rather stepping back a little and seeing the larger interactions. These larger interactions are referred to as design patterns. If the goal of OOP is code reuse, then the goal of design patterns is design reuse.

So, using design patterns is probably something you already do; you just didn't realize it or hadn't put a name to it. Putting names to things and then cataloging and classifying them is important because it allows us to share and communicate with others at a higher level of abstraction. Although there have been several good books written about design patterns, including Patterns for e-business: A Strategy for Reuse by IBM Press, the quintessential reference is Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides or, as it is now commonly referred to, "The Gang of Four Book." "The Gang of Four Book" assigns names and categories to the most common design patterns.

Pattern Categories

So let's take a look at some of the general categories that design patterns fit into and then dig a little deeper into some examples. First, most design patterns can be generalized into a Creational, Behavioral, or Structural pattern. Creational patterns are patterns that help you instantiate objects. The goal of most Creational patterns is to allow you to create objects through at least one level of indirection, which allows you run-time flexibility. Behavioral patterns are concerned with how objects collaborate with each other at run-time to achieve a common goal. The key concept of Behavioral patterns is that a group of coordinated objects can accomplish tasks that a single object could not accomplish on its own. Structural patterns describe methods of class inheritance and object composition.

Creational Patterns

Although there are a number of Creational patterns, an easy one to start with is the Singleton. For most classes, we want to be able to instantiate multiple objects. However, from time to time we have need of a class from which we can instantiate one and only one object. A Singleton has two objectives. First, it must allow for the creation of exactly one object of the type it is responsible for. Second, it must allow for easy access to the object. The following is a scaled down example of a class that I use when I want to establish a database connection.

public class SingletonConnection
{
  private static SingletonConnection _instance = null;
  private static Connection connection = null;
    
  private SingletonConnection()
  {
    // put your code to connect to the database
    // and set the Connection object
    // this.connection = your code here
  }
  
  public static SingletonConnectiongetInstance()
  {
    if (_instance == null )
    {
      _instance = new SingletonConnection();
    }
  
    return _instance;
  }

  public Connection getConnection()
  {
    return this.connection;
  }
}
  

Don't be worried if this class looks very strange to you. The first thing you probably noticed is the private, class-level variable _instance, which is of the same type as the class itself. This allows you to store a single instance of the class in the class itself, but because it is private, it can be accessed only through the public, class-level method getInstance(). The method getInstance() returns the private object if one exists or creates one if needed. The other unusual thing you probably noticed is that the constructor is private. Most programmers are not aware that this is legal syntax. Making the constructor private forces users of the class to use the getInstance() method when they want a database connection. So to add a database connection to any class, we simply add the following line of code.

Connection myConn = SingletonConnection.getInstance().getConnection();


Now, we have fulfilled both of our goals by ensuring that only one object is created and that it is easy to access.

Behavioral Patterns

Of the three pattern categories, I tend to use Behavioral patterns the most. One of the reasons for this is that Java has built-in language constructs for my two favorites, the Observer pattern and the Iterator pattern. These are both patterns that you have probably already discovered on your own.

The Observer pattern is often referred to by one of its aliases, such as Publish/Subscribe or Model/View. The problem the Observer pattern solves is common in, but not limited to, GUI application. Suppose we have some data that is stored in one object and we have several other objects that display this data to an end user in a variety of formats, such as raw numbers, a bar graph, and a line graph. We call the object that contains the data the Observable object and those that are interested in displaying the data the Observers. Java implements the Observer pattern using the classes java.util.Observable and java.util.Observer. We simply have our classes inherit from these base classes and we get all the functionality we need. The Observer classes register with the Observable class by calling its addObserver(Observer o) method. When something happens to its data that it thinks the Observers would be interested in, the Observable class calls its own notifyObservers() method, which in turn calls the update() method of each of the registered Observers. Each of the registered Observers should override the update() method inherited from their parent to take the appropriate action when the Observable object calls notifyObservers(). The call to notifyObservers() is usually tied to some sort of state change in the Observable object data.

Another Behavioral pattern that I use a lot and that is directly supported in Java is the Iterator pattern. Java is loaded with various types of aggregate objects, most of which implement the java.util.Collection interface. One of the methods that an aggregate class implementing java.util.Collection must implement is the iterator() method, which returns a lightweight class that represents all the objects contained within the Collection. The two key methods of Iterator are hasNext() and next(). The method hasNext() tells you if there is another object left in the Iterator, and the next() method returns the next object in the Iterator. The following code assumes that you have instantiated an object called myCollection that implements the java.util.Collection interface.

Iterator myIterator = myCollection.iterator();
while (myIterator.nasNext())
{
  Object myObject = myIterator.next();
  // Put code here to do something with each object in the collection
}


The advantage of using the Iterator pattern is that it decouples how the collection is stored from how it is accessed. In other words, we can change out the object myCollection for any object that implements the Collection interface without changing our code snippet.

Structural Patterns

There are a number of useful Structural design patterns. The most common are the Composite pattern, the Facade pattern, and the Adaptor pattern. The Composite pattern is often used in drawing programs or in user interfaces. The basic idea is that objects are organized into hierarchies, but each node of the hierarchy can itself be a hierarchy and each node can be treated the same way, whether it is a single component or a hierarchy of components. The Facade pattern provides a gateway interface that can be used to wrap a collection of objects inside a single interface. Facades are an excellent way to partition a complex or highly coupled system into subsystems. The Adaptor pattern is used to transform the interface of one class into the interface of another. Adaptors are effective when you have classes that are part of third-party libraries, but their interfaces do not match up well with your system. You simply add an Adaptor class between your system and the third-party class.

Using Patterns

As you have already seen, design patterns use objects and classes as their building blocks. In some cases, one design pattern can be used as a component of another. For example, the list of registered Observers in the Observer pattern is stored in a class that implements a Collection interface for which an Iterator pattern is used to call the update() method on each registered Observer. Although the "Gang of Four Book" list is a good start, there are many more design patterns. In fact, new design patterns are being discovered and published all the time. You will also find that you can create your own patterns based on slight variations in known patterns. For example, imagine if you needed a pool of objects that were instantiated ahead of time and could be returned to the pool when you were done with them. You could modify the Singleton pattern to have a notion of a finite number of instances as well as a method for returning an object when you were finished with it.

Design patterns can also be combined together into larger, systemwide patterns that are often called frameworks. As you begin incorporating design patterns into your systems, you will notice that where you used to design one object at a time, you will now think at a higher level and begin to design things as collections of patterns. A few words of advice: Although you will quickly master several patterns, don't be satisfied until you understand at least the small collection of patterns presented in the "Gang of Four Book." Otherwise, you run the risk of the proverbial carpenter whose only tool is a hammer and therefore views all problems as nails.

Conclusion

Patterns are a way to leverage proven designs. Although you have probably discovered a number of design patterns on your own, having a catalog of patterns with standard names helps us to better communicate about them to each other. A catalog also enables us to combine and derive new patterns more easily. Remember, to use patterns effectively, you should be familiar with as many as possible so you can be sure that you are applying the most appropriate one to a given situation.

Now, the next time you get that feeling of "I've done this before," you will have an extra set of tools at your disposal.

Michael J. Floyd is an Extreme Programmer and the Software Engineering Technical Lead for DivXNetworks. He is also a consultant for San Diego State University and can be reached at This email address is being protected from spambots. You need JavaScript enabled to view it..

Michael Floyd

Michael J. Floyd is the Vice President of Engineering for DivX, Inc.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

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: