Java Design Patterns are divided into three categories – creational, structural, and a very simple design pattern but when it comes to implementation, it comes with a lot of //generating MySql HTML report and Oracle PDF report without. I have written a lot about Java Design Patterns and I got a lot of requests to create an eBook for them. Well, I spent some time in last few weeks and. Design Patterns. FOR Gamma/Helm/Johnson/Vlissides, DESIGN PATTERNS: ELEMENTS OF oriented programming language (Java) for its examples.
|Language:||English, Spanish, German|
|Country:||United Arab Emirates|
|ePub File Size:||17.83 MB|
|PDF File Size:||8.55 MB|
|Distribution:||Free* [*Regsitration Required]|
Java Design Patterns .. Implementing the Abstract Factory Design Pattern. .. programmer can use to solve common problems when designing an. Design patterns represent the best practices used by experienced object- This tutorial will take you through step by step approach and examples using Java. PDF | On Jun 1, , Benneth Christiansson and others published GoF Design Patterns with examples using Java and UML.
This simplification might in some cases reduce the flexibility of the underlying classes, but usually it provides all of the function needed for all but the most sophisticated users. In Figure Depending on which type of Address object we click on, we'd like to see a somewhat different display of that object's properties. Now let's click on the Refresh button to reload the left-hand list box from the original data. You could create a derived class for each of these objects, and in many cases this would be a perfectly acceptable solution. This factory class usually is a Singleton, sinceit needs to keep track of whether a particular instance has been generated.
For Gmail users, check Promotions tab. Make sure to add my email to contacts to avoid this in future too. I subscribed to the mailing list, and within 2 minutes I got the link to the eBook. Thanks for the eBook. To other readers: This is not a scam, this is not a cheap way to collect email addresses — there is indeed a high quality eBook that is sent to your e-mail address.
Thanks Aj, I was waiting for someone to comment like this. I got this book, this is awesome. Thank You Sir. This is great book on Java Design Patters. Compressed in Pages only with a precise information. Can I have the link Please , I have added myself to subscription list …. Hi Pankaj, i am regular follower of your posts. Hi Srini, You need to subscribe to my newsletter to get the email for download link. I checked myself and seems like you are not subscribed.
Also once you are subscribed, since you are using GMail, chances are my emails might land up in Promotions tab. Please use below guide to move my emails to primary tab to fix this once and for all. You should get an email with download link tomorrow. Your email address will not be published. Leave this field empty.
I would love to connect with you personally. You are here: Comments Hi Pankaj, Please send me the link of your design pattern book link. Thank you. I have subscribed and got a link to download but that link is not working. Please check again. Hi, can I write singleton Design Pattern in this way to avoid double checking problem. All well and great BUT………. Thanks and regards Aditi Goyal. I subscribed and received mail, but the link says webpage not available,.
Hi Pankaj, I have subscribed to the link however I did not recieve the download link for the ebook. Thanks Pankaj, I have received this excellent book. You must have got the link in email to download the eBook. Hi Pankaj Thanks For Sharing the book,this book is really good revision material. Regards Mohd Asad Khan. Hi Pankaj, I gave my emailId for downloading the design patterns e-book.
Regards, Vamshi. Could you pleasde mail me the Java Design Patterns ebook? I am unable to download it. Regards Dinesh. Hey Pankaj , Could you please send me Spring ebook download link…I already subscribed for newsletter. Hey Pankaj , Could you please send me java design pattern ebook download link…I already subscribed for newsletter. Hi Girish, Looks like some issue with your subscription, I would request you to unsubscribe and subscribe again to get the email.
Could you please send me one. Hi Pankaj, I am seeing your post regularly. Thanks, Mahesh. Thanks in advance, Komal. Pankaj, Can you please email me the pdf please?
I had subscribed using facebook link. Thank you, Bijoy. Thanks, Pooja. Please send me an email with complete details, what is your intended use etc. The email has been sent to you, please check your Spam folders. Thank u very much, i am looking forward to understand design patterns. Hi Pankaj, Many thanks for the book. Good luck. Best regards, Unisa. Hi Pankaj, The e-Book looks very informative.
Thanks a lot. Hi Pankaj, I am able to download the pdf. It is indeed a very useful stuff. Thanks a lot!!! Hi Pankaj, Please send me the link of your design pattern book link. Thanks, i will check it out and update if required. Hi Pankaj , I did not get mail or may be deleted by chance Can i get it again? Thanks Himanshu. Thanks Pankaj for writing book.
Can i get that mail again? It one of the best sites I just downloaded design patterns book, n i will surely share the feedback soon after reading it. You are doing a great job friend. Thanks again, Arvind. Appreciate your help in educating folks like me… Thanks. Thanks, Muthu. Thanks for sharing. It helps developers to understand clearly and easy to use Design Patterns.
Leave a Reply Cancel reply Your email address will not be published. I am a Software Developer just like you and hate spamming. A Simple Factory pattern returns an instance of one of several possible classes depending on the data provided to it. Usually all classes that it returns have a common parent class and common methods, but each performs a task differently and is optimized for different kinds of data.
This Simple Factory serves as an introduction to the somewhat more subtle Factory Method GoF pattern we'll discuss shortly. It is, in fact, a special subset of that pattern. Figure 3. A Simple Factory pattern. The XFactory class decides which of these subclasses to return depending on the arguments you give it. On the right, we define a getClass method to be one that passes in some value abc, and that returns some instance of the class x. Which one it returns doesn't matter to the programmer since they all have the same methods, but different implementations.
How it decides which one to return is entirely up to the factory. It could be some very complex function, but it is often quite simple. Sample Code Let's consider a simple case in which we could use a Factory class. Suppose we have an entry form and we want to allow the user to enter his name either as "firstname lastname" or as "lastname, firstname. This is a pretty simple sort of decision to make, and you could make it with a simple if statement in a single class, but let's use it here to illustrate how a factory works and what it can produce.
We'll store the split first and last names in the Strings first and last, and, since the subclasses will need access to these variables, we'll make them protected. The Two Subclasses Now we can write two very simple subclasses that split the name into two parts in the constructor. In the FirstFirst class, we make the simplifying assumption that everything before the last space is part of the first name.
In both classes, we also provide error recovery in case the space or comma does not exist. We just test for the existence of a comma and then return an instance of one class or the other.
The complete class diagram is shown in Figure 3. The Namer factory program. We have constructed a simple Java user interface that allows us to enter the names in either order and see the two names separately displayed. This program is shown in Figure 3. The Namer program executing. We type in a name and then click on the Compute button, and the divided name appears in the lower two text fields.
The crux of this program is the compute method that fetches the text, obtains an instance of a Namer class, and displays the results. That's the fundamental principle of the Simple Factory pattern. You create an abstraction that decides which of several possible classes to return and returns one. Then you call the methods of that class instance without ever knowing which subclass you are actually using.
This approach keeps the issues of data dependence separated from the classes' useful methods. Factory Patterns in Math Computation Most people who use Factory patterns tend to think of them as tools for simplifying tangled programming classes. You also can use them in programs that perform mathematical computations. For example, in the Fast Fourier Transform FFT , you evaluate the following four equations repeatedly for a large number of point pairs over many passes through the array that you are transforming.
Because of how the graphs of these computations are drawn, these equations Equations 1—4 constitute one instance of the FFT "butterfly. In this case, your complex math evaluation reduces to Equations 5—8. Since we are making Butterflies, we'll call this Factory a Cocoon. Consider a personal checkbook management program such as Quicken. It manages several bank accounts and investments and can handle your bill paying. Where could you use a Factory pattern in designing a program like that?
Suppose that you are writing a program to assist homeowners in designing additions to their houses. What objects might a Factory pattern be used to produce? The Factory Method We have just seen a couple of examples of the simplest of factories. The factory concept recurs throughout OO programming, and we find examples embedded in Java itself such as the SocketFactory class and in other design patterns such as the Builder pattern, discussed in Chapter 7.
In these cases, a single class acts as a traffic cop and decides which subclass of a single hierarchy will be instantiated. The Factory Method pattern is a clever but subtle extension of this idea, where no single class makes the decision as to which subclass to instantiate.
Instead, the superclass defers the decision to each subclass. This pattern does not actually have a decision point where one subclass is directly selected over another subclass. Instead, a program written using this pattern defines an abstract class that creates objects but lets each subclass decide which object to create. We can draw a pretty simple example from the way that swimmers are seeded into lanes in a swim meet.
When swimmers compete in multiple heats in a given event, they are sorted to compete from slowest in the early heats to fastest in the last heat and arranged within a heat with the fastest swimmers in the center lanes. This is called straight seeding. Now, when swimmers swim in championships, they frequently swim the event twice.
During preliminaries, everyone competes and the top 12 or 16 swimmers return to compete against each other at finals. In order to make the preliminaries more equitable, the top heats are circle seeded, so that the fastest three swimmers are in the center lane in the fastest three heats, the second fastest three swimmers are in the lanes next to center lane in the top three heats, and so on.
So how do we build some objects to implement this seeding scheme and illustrate the Factory Method pattern? First, we design an abstract Event class. The only difference between these classes is that one returns one kind of seeding and the other returns a different kind of seeding.
We also define an abstract Seeding class having the following methods: StraightSeeding and CircleSeeding. Thus we see that we have two hierarchies: We see these two hierarchies illustrated in Figure 4.
The class relationships between Event and Seeding classes. One of them returns an instance of StraightSeeding, and the other returns an instance of CircleSeeding. So you see, there is no real factory decision point as we had in our simple Namer example. Instead, the decision as to which Event class to instantiate determines which Seeding class will be instantiated. TE While it looks like there is a one-to-one correspondence between the Seeding and Event class hierarchies, there needn't be.
There could be many kinds of Events and only a few kinds of Seeding that they use. The Event class reads in the Swimmers to a Vector from some database a file, in this example and then passes that Vector to the Seeding class when we call the getSeeding method for that event. The Event Classes We have seen the abstract base Event class earlier. We actually use it to read in the swimmer data here from a file and pass it on to instances of the Swimmer class to parse. So we instantiate our StraightSeeding class and copy in the Vector of swimmers and the number of lanes.
Then a call to super. This simplifies things because we will always need to seed the remaining heats by straight seeding. Then we seed the last 2 or 3 heats as shown previously, and we are done with that type of seeding as well. You can see the results of these two seedings in Figure 4. Figure 4. Straight seeding of the yard and circle seeding of the yard freestyles. Other Factories Now one issue that we have skipped over is how the program that reads in the swimmer data decides which kind of event to generate.
We finesse this here by calling the two constructors directly: This revisits the simple factory we began the discussion with. When to Use a Factory Method You should consider using a Factory method under the following circumstances: A class uses its subclasses to specify which objects it creates.
You want to localize the knowledge of which class gets created. There are several variations on the Factory pattern. The base class is abstract, and the pattern must return a complete working class. The base class contains default methods and is subclassed only when the default methods are insufficient. Parameters are passed to the factory telling it which of several class types to return.
In this case, the classes may share the same method names, but each may do something quite different. Seeding in track is carried out from inside to outside lanes.
What classes would you need to develop to carry out track-like seeding? You can use this pattern to return one of several related classes of objects, each of which can return several different objects on request. In other words, the Abstract Factory is a factory object that returns one of several groups of classes. You might even decide which class to return from that group by using a Simple Factory.
One classic application of the Abstract Factory pattern is when your system needs to support multiple look-and-feel user interfaces, such as Windows 9x, Motif, and Macintosh. You tell the factory that you want your program to look like Windows, and it returns a GUI factory that returns Windows-like objects. Then when you request specific objects, such as buttons, check boxes, and windows, the GUI factory returns Windows instances of these visual interface components. In Java 1. In the following code, we find the name of the current windowing system and then tell the pluggable look-and-feel PLAF Abstract Factory to generate the correct objects.
Suppose you are writing a program to plan the layout of gardens. These could be annual gardens, vegetable gardens, or perennial gardens. No matter the type of garden, we want to ask the same questions: What are good center plants?
What are good border plants? What plants do well in partial shade? We want a base Garden class that can answer these questions. It defines the methods of a concrete class that can return one of several classes, in this case one each for center, border, and shade-loving plants. The Abstract Factory could also return more-specific garden information, such as soil pH and recommended moisture content. In a real system, for each type of garden we would probably consult an elaborate database of plant information.
In this example, we'll return one kind of plant from each category. So, for example, for the vegetable garden we write the following: Each of these concrete classes is a Concrete Factory, since it implements the methods outlined in the parent abstract class.
Now we have a series of Garden objects, each of which returns one of several Plant objects. This is illustrated in the class diagram in Figure 5. Figure 5. The major objects in the Gardener program. The user interface of the Gardener program. How the User Interface Works This simple interface consists of two parts: When you click on one of the garden types, this causes the program to return a type of garden that depends on which button you select.
At first, you might think that we would need to perform some sort of test to decide which button was selected and then instantiate the right Concrete Factory class.
However, a more elegant solution is to create a different ItemListener for each radio button as an inner class and have each one create a different garden type. First, we create the instances of each Listener class. Adding More Classes 40 One of the great strengths of the Abstract Factory pattern is that you can add new subclasses very easily. For example, if you need a GrassGarden or a WildflowerGarden, you can subclass Garden and produce these classes.
The only real change that you'd need to make in any existing code is to add some way to choose these new kinds of gardens. Consequences of the Abstract Factory Pattern One of the main purposes of the Abstract Factory is that it isolates the concrete classes that are generated. The actual names of these classes are hidden in the factory and need not be known at the client level. Because of the isolation of classes, you can change or interchange these product class families freely.
Further, since you generate only one kind of concrete class, this system keeps you from inadvertently using classes from different families of products. However, adding new class families takes some effort because you must define new, unambiguous conditions that cause such a new family of classes to be returned. AM FL Y While all of the classes that the Abstract Factory pattern generates have the same base class, nothing prevents some subclasses from having additional methods that differ from the methods of other classes.
For example, a BonsaiGarden class might have a Height or WateringFrequency method that is not present in other classes. This creates the same problem as occurs in any subclasses. That is, you don't know whether you can call a class method unless you know whether the subclass is one that allows those methods.
This problem has the same two solutions as does any similar case. Either you can define all of the methods in the base class, even if they don't always have an actual function. Or, if you can't change the base class, you can derive a new base class that contains all of the methods that you need and then subclass that for all of your garden types.
TE lightbulb Thought Question 1. Suppose that you are writing a program to track investments, such as stocks, bonds, metal futures, and derivatives. How could you use an Abstract Factory pattern? The Singleton pattern In this chapter, we'll take up the Singleton pattern.
This pattern is grouped with the other Creational patterns, although it is to some extent a pattern that limits, rather than promotes, the creation of classes. Specifically, it ensures that there is one and only one instance of a class and provides a global point of access to that instance. Any number of cases in programming in which you need to ensure that there can be one and only one instance of a class are possible.
For example, your system might have only one window manager or print spooler or one point of access to a database engine. Or, your computer might have several serial ports, but there can only be one instance of COM1. Creating a Singleton Using a Static Method The easiest way to create a class that can have only one instance is to embed a static variable inside of the class that is set on the first instance and then check for it each time that you enter the constructor.
A static variable is a variable for which there is only one instance, no matter how many instances of the class exist. To prevent instantiating the class more than once, make the constructor private so that an instance can be created only from within the static method of the class. Then we create a method called Instance, which will return an instance of Spooler, or null, if the class has already been instantiated. This is illustrated in the following code: And, should you try to create instances of the PrintSpooler class directly, creating instances will fail at compile time because the constructor has been declared as private.
If instead you want to know whether a spooler has been created and that you cannot create another, you can return a null if the spooler already exists, or you can throw an exception. Assuming that programmers will always remember to check for errors is the beginning of a slippery slope that many prefer to avoid.
Instead, you can create a class that throws an exception if you attempt to instantiate it more than once. This requires the programmer to take action and is thus a safer approach. Let's create our own exception class for this case. However, it is convenient to have our own named exception type so that the compiler will warn us of the type of exception we must catch when we attempt to create an instance of PrintSpooler.
Throwing an Exception Let's write the skeleton of our Spooler class—we'll omit all of the printing methods and just concentrate on correctly implementing the Singleton pattern: Remember that we must enclose every method that may throw an exception in a try-catch block. Opening one spooler printer opened Opening two spoolers Only one spooler allowed The last line indicates that an exception was thrown as expected.
Providing a Global Point of Access to a Singleton Pattern Since a Singleton pattern is used to provide a single point of global access to a class, your program design must provide for a way to reference the Singleton throughout the program, even though Java has no global variables.
One solution is to create such Singletons at the beginning of the program and pass them as arguments to the major classes that might need to use them. This could have performance implications. A more elaborate solution is to create a registry of all of the program's Singleton classes and make the registry generally available. Each time a Singleton is instantiated, it notes that in the registry. Then any part of the program can ask for the instance of any Singleton using an identifying string and get back that instance variable.
And, of course, the registry itself is probably a Singleton and must be passed to all parts of the program using the constructor of various set functions. Probably the most common way to provide a global point of access is by using static methods of a class.
The class name is always available, and the static methods can be called only from the class and not from its instances, so there is never more than one such instance no matter how many places in your program call that method. This is the approach used in the Java serial port package, javax. The javax. This package is designed to provide control over the serial and parallel ports of a computer. Each supported platform has a different implementation of this package, since it must include native code to handle the actual system hardware.
Serial ports are a good example of a resource that should be represented by a Singleton, since only one program at a time can access a serial port, and even within a program only one module or group of modules should be communicating over the port. Actually, two Singletons are possible here: In the javax. This package handles both parallel and serial ports, so you also need to filter the returned objects to allow only the serial ports.
Further, since it is a static method, multiple instances are not allowed. You can call this method only from the class and not from its instances. Each CommPortIdentifier instance returned from this enumeration has a distinct port name, which you can access using the getName method.
This enumeration consists of all possible ports for the system, whether opened or not, implemented or not. If the port doesn't exist at all, the open method throws the NoSuchPortException; if the port is in use by another program, it throws the PortInUseException. The code for handling this looks like the following: The important thing is that the CommPort cp is non-null only if no exceptions are thrown. We illustrate the use of these ports in the SimpleComm program shown in Figure 6. Figure 6.
The SimpleComm program executing, showing how it represents ports that do not exist and those that are not owned.
In addition, we added the bogus COM5 port to show the error message it generates. Clicking on each port in turn opens that port and assigns it to the SimpleComm program. However, the getCurrentOwner method returns the message "Port currently not owned," which means it really didn't exist in the first place. When we again click on COM2, we find that it is now in use as well, and by this program.
You might ask whether each port is a Singleton. There can be many instances of a port, but you can have only one open at a time. This certainly is providing a single global point of access and making sure that only one can be used at a time. Thus we can probably view the opened ports as Singletons as well. We expect the class to allow us to enumerate the available ports and open any of them. Some of the methods in such a class might be as follows: The getAllPorts method is just like the one shown previously, when we enumerated the ports.
However, the getAvailablePorts method is interesting because we don't need to do anything at all when we catch the port exceptions. We get the port and try to open it.
If neither operation fails, we add the port name to the list of available ports. The available ports assigned and then in use. Which are the Singletons here? We really just wrapped the CommPortIdentifier methods so that we could handle the exceptions internally. The static CommPortIdentifier method might be considered a Singleton registry, since it provides access to four or more different ports. However, as a static method it does provide the single point of access. The ports themselves remain the Singletons, since only one instance of an opened port can exist.
Subclassing a Singleton can be difficult, since this can work only if the base Singleton class has not yet been instantiated. You can easily change a Singleton to allow a small number of instances, where this is allowed and meaningful.
Consider a system for processing ATM card transactions. A thief is using a stolen ATM card number to steal funds, concurrent with the legitimate user's withdrawing funds. How could you design a Singleton to reduce this risk? Java 49 Chapter 7. The Builder Pattern In this chapter we'll consider how to use the Builder pattern to construct objects from components. We have already seen that the Factory Pattern returns one of several different subclasses, depending on the data passed in arguments to the creation methods.
But suppose we don't want just a computing algorithm, but rather a whole different user interface, depending on the data we need to display. A typical example might be your e-mail address book. You probably have both people and groups of people in your address book, and you expect the display for the address book to change so that the People screen has places for first and last names, company name, e-mail address, and telephone number.
On the other hand, if you were displaying a group address page, you'd like to see the name of the group, its purpose, and a list of its members and their e-mail addresses.
You click on a person's name and get one display and click on a group's name and get the other display. Let's assume that all e-mail addresses are kept in an Address object and that People and Group classes are derived from this base class, as shown in Figure 7. Figure 7. Both Person and Group are derived from Address. Depending on which type of Address object we click on, we'd like to see a somewhat different display of that object's properties. This is little more than just a Factory pattern because the objects returned are not simple descendents of a base display object, but rather totally different user interfaces made up of different combinations of display objects.
The Builder pattern assembles a number of objects, such as display widgets, in various ways depending on the data. Furthermore, since Java is one of the few languages with which you can cleanly separate the data from the display methods into simple objects, Java is the ideal language to implement the Builder pattern.
An Investment Tracker 50 Let's consider a somewhat simpler case in which it would be useful to have a class build our GUI for us. Suppose that we want to write a program to keep track of the performance of our investments, for example, stocks, bonds, and mutual funds.
We want to display a list of our holdings in each category so that we can select one or more of the investments and plot their comparative performances. Even though we can't predict in advance how many of each kind of investment we might own at any given time, we want a display that is easy to use for either a large number of funds such as stocks or a small number of funds such as mutual funds.
In each case, we want some sort of multiple choice display so that we can select one or more funds to plot. If there is a large number of funds, we'll use a multichoice list box; if there are three or fewer funds, we'll use a set of check boxes. We want our Builder class to generate an interface that depends on the number of items to be displayed and yet have the same methods for returning the results. Our displays are shown in Figure 7.
The first display, Figure 7. TE Now, let's consider how we can build the interface to carry out this variable display. We'll start with a multiChoice abstract class that defines the methods that we need to implement.
The two displays we're using here—a check box panel and a list box panel—are derived from this abstract class. Calling the Builders Since we're going to need one or more builders, we might call our main class Architect or Contractor.
However, here we're dealing with lists of investments, so we'll just call it wealthBuilder. In this main class, we create the user interface, consisting of a BorderLayout with the center divided into a 1-x-2 GridLayout. The left part of the grid contains our list of investment types and the right an empty panel that we'll fill depending on the kinds of investments selected. We load them with arbitrary values as part of program initializing. Then, when the user clicks on one of the three investment types in the left list box, we pass the equivalent Vector to our Factory, which returns one of the Builders: We could just as easily have attached adifferent ActionListener to each of the three buttons.
We do save the multiChoice panel that the factory creates in the mchoice variable so that we can pass it to the Plot dialog. The List Box Builder The simpler of the two builders is the list box builder. The getUI method returns a panel containing a list box showing the list of investments. Here we need to find out how many elements are to be displayed and then create a horizontal grid of that many divisions.
Then we insert a check box in each grid line. We illustrate the final UML class diagram in Figure 7. The Builder class diagram. A Builder pattern lets you vary the internal representation of the product that it builds.
It also hides the details of how the product is assembled. Each specific Builder is independent of any others and of the rest of the program. This improves modularity and makes the addition of other Builders relatively simple.
Because each Builder constructs the final product step by step, depending on the data, you have more control over each final product that a Builder constructs. A Builder pattern is somewhat like an Abstract Factory pattern in that both return classes made up of a number of methods and objects.
The main difference is that while the Abstract Factory returns a family of related classes, the Builder constructs a complex object step by step depending on the data presented to it. Some word processing and graphics programs construct menus dynamically based on the context of the data being displayed. How could you use a Builder effectively here? Not all Builders must construct visual objects.
For the personal finance industry, what could you construct using a Builder? Suppose that you are scoring a track meet made up of five to six different events. How can you use a Builder in such a situation? The Prototype Pattern With the Prototype pattern, you can specify the general class needed in a program but defer specifying the exact class until execution time.
It is similar to the Builder pattern in that some class decides what components or details make up the final class. However, it differs in that the target classes are constructed by cloning one or more prototype classes and then changing or filling in the details of the cloned class to behave as desired. Prototypes can be used whenever you need classes that differ only in the type of processing that they offer, for example, when parsing strings that represent numbers in different radixes.
In this sense, the Prototype is nearly the same as the Exemplar pattern described by Coplien . Let's consider the case in which you need to make a number of queries to an extensive database to construct an answer. Once you have this answer as a table or ResultSet, you might want to manipulate it to produce other answers without your having to issue additional queries.
For example, consider a database of a large number of swimmers in a league or statewide organization. Each swimmer swims several strokes and distances throughout a season. The best times for swimmers are tabulated by age group.
Within a single four-month season, many swimmers will have birthdays and therefore move into new age groups. Thus the query to determine which swimmers did the best in their age groups that season depends on the date of each meet and on each swimmer's birthday. The computational cost of assembling this table of times is therefore fairly high. Once you have a class containing this table, sorted by sex, you might want to examine this information sorted by time or by actual age rather than by age group.
Recomputing this data isn't sensible, and you don't want to destroy the original data order, so some sort of copy of the data object is desirable. Cloning in Java You can make a copy of any Java object using the clone method. Thus you must cast it to the actual type of the object that you are cloning.
Three other significant restrictions apply to this method: It is a protected method and can be called only from within the same class or a subclass. You can clone only objects that are declared to implement the Cloneable interface.
All arrays are considered to implement the Cloneable interface. Since the clone method is protected, this suggests packaging the public, visible clone method inside of the class, where it can access that protected clone method. In this case, method names such as make are probably more descriptive and suitable.
Using the Prototype Now let's write a simple program that reads data from a database and then clones the resulting object. In our example program, SwimInfo, we just read these data from a file, but the original data were derived from a large database as we mentioned previously.
Then we create a class called Swimmer that holds one swimmer's name, age, sex, club, and time. Once we've read the data into SwimInfo, we can display it in a list box. Then, when the user clicks on the Clone button, we'll clone this class and sort the data differently in the new class. Again, we clone the data because creating a new class instance would be much slower, and we want to keep the data in both forms.
In Figure 8. Figure 8. Prototype example. Now let's click on the Refresh button to reload the left-hand list box from the original data. The somewhat disconcerting result is shown in Figure 8. Prototype example, after clicking on Clone and then on Refresh. Why have the names in the left-handed list box also been re-sorted?
This occurs in Java because the clone method is a shallow copy of the original class. In other words, the references to the data objects are copies, but they refer to the same underlying data. Thus any operation performed on the copied data will also be done on the original data in the Prototype class.
In some cases, this shallow copy might be acceptable, but if you want to make a deep copy of the data, you must write a deep cloning routine of your own as part of the class you want to clone.
In this simple class, you just create a new Vector using a constructor that creates the new instance and copies the elements of the old class's Vector into the new one. As long as all of the classes have the same interface, they can actually be from entirely different class hierarchies. Let's consider a more elaborate example of the listing of swimmers we discussed previously. Instead of just sorting the swimmers, let's create subclasses that operate on the data, modifying it and presenting the result for display in a list box.
We start with the abstract class SwimData, which has all abstract methods except for the deepClone method we just described. We always start with the TimeSwimData class and then clone it for various other displays. For example, the SexSwimData class resorts the data by sex and displays only one sex, as shown in Figure 8. The SexSwimData class displays only one sex, shown on the right. This class has the following additional method: Thus when you use the prototype to clone a copy of the base TimeSwimData class to make an instance of SexSwimData, we can also tell it which sex to display.
Classes do not even have to be that similar, however. The AgeSwimData class takes the cloned input data array and creates a simple histogram by age. If you have been displaying the boys, you see their age distribution, and if you have been displaying the girls, you see their age distribution, as shown in Figure 8. The AgeSwimData class displays an age distribution. In other words, the Prototype pattern effectively hides the concrete products from the client, in this case the display list.
The same getName and size methods are used as in the superclasses, but here the displayed data are quite different. As long as the concrete product classes have the same interface, the Prototype is a suitable pattern choice. We have defined a different concrete class female or male swimmer list by creating a class and setting parameters within that class.
The UML diagram in Figure 8. It keeps two instances of SwimData but does not specify which ones. You could easily create additional concrete classes and register them with whatever code selects the appropriate concrete class.
In our previous example program, the user is the deciding point or factory, because he simply clicks on one of several buttons. In a more elaborate case, each concrete class could have an array of characteristics, and the decision point could be a class registry or prototype manager, which examines these characteristics and selects the most suitable class.
In Java, you can load additional classes dynamically at runtime and make them available through this registry. You could also combine the Factory Method pattern with the Prototype pattern to have each of several concrete classes use a concrete class different from those available. Prototype Managers A prototype manager class can be used to decide which of several concrete classes to return to the client.
It can also manage several sets of prototypes at once. For example, in addition to returning one of several classes of swimmers, it could return different groups of swimmers who swam different strokes and distances. It could also manage which list boxes of several types are returned and to display them, including tables, multicolumn lists, and graphical displays.
It is important that whichever subclass is returned does not require casting to a new class type in order to be used in the program. In other words, the methods of the parent abstract or base class should be sufficient, and the client should never need to know which actual subclass it is dealing with. Cloning Using Serialization 65 Here is a clever trick, which some have called a "hack," for cloning using the serializable interface.
A class is said to be serializable if you can write it out as a stream of bytes and then read those bytes back in to reconstruct the class. However, if we declare both the Swimmer and SwimData classes as Serializable, public class SwimData implements Cloneable, Serializable class Swimmer implements Serializable we can write the bytes to an output stream and reread them to create a complete data copy of that instance of a class.
Consequences of the Prototype Pattern Using the Prototype pattern, 1. You can add and remove classes at runtime by cloning them as needed. You can revise the internal data representation of a class at runtime based on program conditions. You can also specify new objects at runtime without creating a proliferation of classes and inheritance structures. One difficulty in implementing the Prototype pattern in Java is that if the classes already exist, you might not be able to change them to add the required clone or deepClone methods.
Using the deepClone method can be particularly difficult if all of the class objects contained in a class cannot be declared serializable.
In addition, classes that have circular references to other classes cannot be cloned. You might be able to clone an existing class rather than writing one from scratch. Note, however, that every class that you might use as a prototype must itself be instantiated perhaps at some expense in order for you to use a Prototype registry. This can be a performance drawback. Finally, the idea of having Prototype classes to copy implies that you have sufficient access to the data or methods in these classes to change them after cloning.
This might require adding data access methods to these prototype classes so that you can modify the data once you have cloned the class. An entertaining banner program shows a slogan starting at different places on the screen at different times and in different fonts and sizes. Design the program using a Prototype pattern. Clones using serialization. Abstract Factory pattern returns one of several groups of classes. In some cases, it actually returns a Factory pattern for that group of classes.
Builder pattern assembles a number of objects to make a new object, based on the data with which it is presented. Often the choice of which way the objects are assembled is achieved using a Factory pattern. Prototype pattern copies or clones an existing class rather than creating a new instance, when creating new instances is more expensive.
Singleton pattern ensures that there is one and only one instance of an object and that it is possible to obtain global access to that one instance. Structural Patterns A structural pattern describes how classes and objects can be combined to form larger structures. Class and object patterns differ in that a class pattern describes how inheritance can be used to provide more useful program interfaces.
An object pattern describes how objects can be composed into larger structures using object composition or by including objects within other objects.
We'll also look at a number of other structural patterns where we combine objects to provide new functionality. Proxy pattern creates a simple object that takes the place of a more complex object which may be invoked later, such as when the program runs in a networked environment. Flyweight pattern for sharing objects, where each instance does not contain its own state, but stores it externally.
This approach allows efficient sharing of objects to save space when there are many instances, but only a few different types.
Bridge pattern separates an object's interface from its implementation so you can vary them separately. Decorator pattern lets you add responsibilities to objects dynamically. You'll see that there is some overlap among these patterns and even some overlap with the Behavioral patterns in the next section. We'll summarize these similarities after we have described all of the patterns.
The Adapter Pattern The Adapter pattern converts the programming interface of one class into that of another. You use adapters whenever you want unrelated classes to work together in a single program.
The concept of an adapter is thus pretty simple: You write a class that has the desired interface and then make it communicate with the class that has a different interface.
There are two ways to do this: In the first, you derive a new class from the nonconforming one and add the methods that you need to make the new derived class match the desired interface.
In the second, you include the original class inside the new one and create the methods to translate calls within the new class. These two approaches, termed class adapters and object adapters, are both fairly easy to implement in Java. Moving Data between Lists Let's consider a simple Java program that allows you to enter names into a list and then select some of those names to be transferred to another list.
The initial list in the example consists of a class roster, and the second list consists of class members who will be doing advanced work. In this simple program, shown in Figure 9. Then, to move a name to the righthand list box, you click on it and then click on Add. To remove a name from the right-hand list box, click on it and then on Remove.
This moves the name back to the left-hand list. Figure 9. A simple program to enter and choose names. It consists of a GUI creation constructor and an actionListener routine for the three buttons. A Command pattern, or even a simple set of if statements, can then call the following actions on the two lists: Most of the methods you use for creating and manipulating the user interface remain the same.
In fact, because the JList class was designed to represent far more complex kinds of lists, there are virtually no methods in common between the classes. The JList class is a window container that has an array, Vector, or other ListModel class associated with it.
It is this ListModel that actually contains and manipulates the data. Further, the JList class does not contain a scroll bar but instead relies on being inserted in the viewport of the JScrollPane class. Data in the JList class and its associated ListModel are not limited to strings; they may be almost any kind of objects, as long as you provide the cell drawing routine for them.
This makes it possible to have list boxes with pictures illustrating each choice in the list. In this case, we are going to create a class that only emulates the List class, which here needs only the three methods shown in the previous table. We can define the needed methods as an interface and then make sure that the class that we create implements those methods. So you cannot create a class that inherits from JList and List at the same time.
However, you can create a class that inherits from one class hierarchy and implements the methods of another. In most cases, this is quite a powerful solution. Thus, by using the implements keyword, we can have the class take on the methods and appearance of being a class of either type. The Object Adapter In the object adapter approach, shown in Figure 9. Since the outer container for a JList is not the list element at all but the JScrollPane that encloses it, we are really adding methods to a subclass of JScrollPane that emulate the methods of the List class.
These methods are in the interface awtList. An object adapter approach to the list adapter. This class is derived from the AbstractListModel, which defines the methods listed in the following table: Method Purpose Adds a listener for changes in the data. Calls this after any change occurs between the two indexes min and max. Calls this after any data have been added between min and max. Calls this after any data have been removed between min and max.
The three fire methods provide the communication path between the data stored in the ListModel and the actual displayed list data. Firing them causes the displayed list to be updated. In this case, the addElement, and removeElement methods are all that are needed, although you could imagine a number of other useful methods. Each time that we add data to the data vector, we call the fireIntervalAdded method to tell the list display to refresh that area of the displayed list.
A class adapter approach to the List adapter. The List class constructor allows you to specify the length of the list in lines.
There is no way to specify this directly in the JList class. You can compute the preferred size of the enclosing JScrollPane class based on the font size of the JList, but depending on the layout manager, this might not be honored exactly. The object adapter o Could allow subclasses to be adapted by simply passing them in as part of a constructor. Two-Way Adapters The two-way adapter is a clever concept that allows an object to be viewed by different classes as being either of type awtList or type JList.
This is most easily carried out by a class adapter, since all of the methods of the base class are automatically available to the derived class. However, this can work only if you do not override any of the base class's methods with methods that behave differently. As it happens, the JawtClassList class is an ideal two-way adapter because the List and JList classes have no methods in common.
Note in the UML diagram in Figure 9. Thus you can refer to the awtList methods or to the JList methods equally conveniently and treat the object as an instance either of JList or of awtList. Pluggable Adapters A pluggable adapter is an adapter that adapts dynamically to one of several classes. Of course, the adapter can adapt only to classes that it can recognize, and usually the adapter decides which class it is adapting to based on differing constructors or setParameter methods.
Java has yet another way for adapters to recognize which of several classes it must adapt to: You can use reflection to discover the names of public methods and their parameters for any class.
For example, for any arbitrary object you can use the getClass method to obtain its class and the getMethods method to obtain an array of the method names.
It is easier to use if you know the name of the method that you are looking for and simply want to find out the arguments that it requires. From that method signature, you can then deduce the adaptations that you need to carry out. However, because Java is a strongly typed language, you more likely would simply invoke the adapter using one of several constructors, with each constructor tailored for a specific class that needs adapting.
Adapters in Java In a broad sense, a number of adapters are already built into the Java language. In this case, the Java adapters serve to simplify an unnecessarily complicated event interface.
One of the most commonly used of these Java adapters is the WindowAdapter class. One inconvenience of Java is that windows do not close automatically when you click on the Close button or window Exit menu item. The general solution to this problem is to have your main Frame window implement the WindowListener interface and leave all of the Window events empty except for windowClosing.
The Window Adapter class is provided to simplify this procedure. This class contains empty implementations of all seven of the previous WindowEvents. You then need only to override the windowClosing event and insert the appropriate exit code.
One such simple program is shown next. An object adapter version. The Bridge Pattern At first sight, the Bridge pattern looks much like the Adapter pattern in that a class is used to convert one kind of interface to another. However, the Adapter pattern is intended to make one or more classes' interfaces look the same as that of a particular class. By contrast, the Bridge pattern is designed to separate a class's interface from its implementation so that you can vary or replace the implementation without changing the client code.
Suppose that you have a program that displays a list of products in a window. The simplest interface for that display is a JList box. But once a significant number of products have been sold, you might want to display the products in a table along with their sales figures. Since we have just discussed the adapter pattern, you think immediately of the class-based adapter, where we adapt the fairly elaborate interface of the JList to our simpler needs in this display.
In simple programs, this will work fine, but as we'll see, there are limits to that approach. Further, let's suppose that we need to produce two kinds of displays from our product data, a customer view that is just the list of products we've mentioned and an executive view that also shows the number of units shipped. We'll display the product list in an ordinary JList box and the executive view in a JTable display.
These two displays are the implementations of the display classes, as shown in Figure Figure Two displays of the same information using a Bridge pattern. Now, we want to define a single, simple interface that remains the same regardless of the type and complexity of the actual implementation classes.
We'll start by defining an abstract Bridger class. Here we'll have them add the data lines to the display one at a time. In this simple example, we separate the quantity from the name with two dashes and parse these apart within the list classes.
The Bridge between the interface on the left and the implementation on theright is the listBridge class, which instantiates one or the other of the list display classes. Note that it extends the Bridger class for the use of the application program. The Bridger class on the left is the Abstraction, and the listBridge class is the implementation of that abstraction.
The visList interface defines the interface of the Implementor, and the Concrete Implementors are the productList and productTable classes. The UML diagram for the Bridge pattern used in the two displays of product information. Note that these two concrete implementors are quite different in their specifics even though they both support the visList interface. Extending the Bridge Now suppose that we need to make some changes in the way these lists display the data.
For example, you might want to have the products displayed in alphabetical order. You might think you'd need to either modify or subclass both the list and table classes. This can quickly get to be a maintenance nightmare, especially if more than two such displays eventually are needed. Instead, we simply make the changes in the extended interface class, creating a new sortBridge class from the parent listBridge class. The converse is also true. For example, you could create another type of list display and replace one of the current list displays without any other program changes, as long as the new list also implements the visList interface.
In the example in Figure The ordinary list is replaced without any change in the public interface to the classes. Another display using a Bridge to a tree list.
A Java Bean is a reusable software component that can be manipulated visually in a Builder tool. All of the JFC components are written as Beans, which means that they support a query interface using the Introspector class that enables builder programs to enumerate their properties and display them for easy modification.
The builder panel to the right shows how you can modify the properties of either of those components by using a simple visual interface. The property lists are implemented using a Bridge pattern. The actual program you construct uses these classes in a conventional way, each having its own rather different methods.
However, from the builder's point of view, they all appear to be the same. Consequences of the Bridge Pattern Using the Bridge pattern has the following consequences: The Bridge pattern is intended to keep the interface to your client program constant while allowing you to change the actual kind of class that you display or use. This can help you to avoid recompiling a complicated set of user interface modules and require only that you recompile the bridge itself and the actual end display class.
You can extend the implementation class and the Bridge class separately and usually without their having much interaction with each other.
You can hide implementation details from the client program much more easily. In plotting a stock's performance, you usually display the price and price-earnings ratio over time, while in plotting a mutual fund, you usually show the price and the earnings per quarter. Suggest how you can use a Bridge pattern to do both.