1.08k likes | 1.21k Vues
Unit 22 Abstract Factory. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 17 Abstract Factory. Summary prepared by Kirk Scott. The Introduction Before the Introduction. Like some of the other patterns in this group, this pattern turns out to be pretty simple
E N D
Unit 22Abstract Factory Summary prepared by Kirk Scott
Design Patterns in JavaChapter 17Abstract Factory Summary prepared by Kirk Scott
The Introduction Before the Introduction • Like some of the other patterns in this group, this pattern turns out to be pretty simple • The book, as usual, tries to provide several examples with context • Although more information should be useful, the presentation seems to partially confuse the presentation of the basic pattern • I will try to work through this, adding explanations that help keep it clear what part of the material directly illustrates the pattern and what is background
Book definition: • The intent of the Abstract Factory, or Kit, is to allow creation of families of related or dependent objects.
Comment mode on, 1: • The name of the pattern includes the word abstract • For better or worse, the book’s examples don’t include an abstract class • Instead, the examples show a concrete superclass and a subclass of it • It seems that an example that more closely followed the name of the pattern would have an abstract class and two concrete subclasses of it
Comment mode on, 2: • Once you see the word kit in the book definition, you might be put in mind of the chapter on facades • There, the goal was to create a class that made it easy to use a toolkit or utility, for example • In a way, that chapter worked at its goal backwards • The examples identified application specific logic and implemented that in a set of classes
The façade was a class that made it easier to create and use graphical user interface elements in the application • Even though the point of those examples was the façade, the heavy work was in dealing with the application specific parametric equations • It was almost as if the leftovers in the design ended up in the UI class, which was the facade
In this chapter, the emphasis is on the user interface stuff • In fact, you might regard the user interface class as a façade into the Java API • However, at this time the façade aspects of the design are not what the book is emphasizing • In effect, what’s happening is that the façade idea is being expanded out into a set of classes • It’s this expansion into a set of classes that’s of interest
In its simplest form, this is how the book illustrates what’s going on • In a base UI class you define methods that will return instances of graphical user interface components that have certain features • For example, an application may require a button
Rather than having the application construct an instance of JButton directly, it acquires a JButton object by calling a UI method • The method that constructs the JButton takes care of the details of what kind of construction parameters it will use
This grows into the Abstract Factory design pattern in this way: • What if you would like it to be possible for the application to seamlessly use JButtons of a different form? • The you extend the UI class, overriding those methods where you would like the visual aspects to change
The application can use the subclass of the original UI class • When the application calls the method to get an instance of a JButton, it will get the kind defined in the subclass
A Classic Example: GUI Kits • A GUI kit is an implementation of the Abstract Factory design pattern • The GUI kit supplies components to client applications • These components are things like buttons or other graphical user interface components • The kit constructs the component objects, passing in parameters so that together they have a consistent look and feel
A simple illustration of the abstract factory idea is given in the UML diagram on the next overhead • The UI class implements methods that have to do with the visual appearance of an application • Notice that the diagram includes a BetaUI subclass • This represents the idea that if desired, the same set of methods could be provided, but returning objects with different visual characteristics
Before going any further, observe the following: • It might be a better illustration of the pattern overall if there were an abstract superclassAbstractUI • Then this could have two subclasses, NormalUI and BetaUI • However, the book has chosen to do it with a simple superclass and subclass, so the example will be pursued in that way
The UML diagram on the following overhead illustrates the idea that a client application makes use of the UI class • Specifically, it previews the idea that the undoButton of the application may be derived from the createButton() method, or some similar method in the UI class • If, in the diagram, the BetaUI class were substituted for the UI class, then the Visualization application would get a different look and feel
The book illustrates the idea with what is in reality a pretty simple example • The figure on the next overhead illustrates the graphical user interface for a Visualization application • The application makes it possible to: • add icons representing machines, • click and drag them around the work area, • and undo a recent action, like adding a machine
The figure on the next overhead shows the application with (slight) changes in the user interface • The add and undo button images have been changed from rockets to cherries • The text under the images has been made italic • Yes, the change could be made by simply hardcoding a change somewhere in the UI • However, it will be accomplished by creating a subclass of UI which has these different characteristics hardcoded into it
The UML diagram for the UI class showed these methods: • createButton(), • getFont(), • createPaddedPanel(), • and getIcon()
This is only a subset of the methods it would contain • In continuing the example, the book considers these methods: • createButton(), • createButtonOk(), • and createButtonCancel() • Code for these is given on the following overheads
public JButtoncreateButton() • { • JButton button = new JButton(); • button.setSize(128, 128); • button.setFont(getFont()); • button.setVerticalTextPosition(AbstractButton.BOTTOM); • button.setHorizontalTextPosition(AbstractButton.CENTER); • return button; • }
public JButtoncreateButtonOk() • { • JButton button = createButton(); • button.setIcon(getIcon(“images/rocket-large.gif”)); • button.setText(“Ok!”); • return button; • }
public JButtoncreateButtonCancel() • { • JButton button = createButton(); • button.setIcon(getIcon(“images/rocket-large-down.gif”)); • button.setText(“Cancel!”); • return button; • }
Notice that the creation of the OK and the Cancel buttons make use of the creation of a simple button • In this code, the use of the rocket icon/image is hardcoded into the characteristics of the buttons • Then in the visualization application, these button creation methods are used to create visual components
In particular, if you look at the constructor for the Visualization client, it takes an instance of the UI class as a parameter • Also, the visualization has a (protected) instance variable named undoButton of the (super) type JButton
On the following overhead the code is given for a method named undoButton() in the visualization • This method returns an instance of an undoButton which it creates • This method makes use of the button creation methods in the UI class
protected JButtonundoButton() • { • if(undoButton == null) • { • undoButton = ui.createButtonCancel(); • undoButton.setText(“Undo”); • undoButton.setEnabled(false); • undoButton.addActionListener(mediator.undAction()); • } • return undoButton; • }
The visualization code accepts a UI object as a construction parameter • This means that the look and feel of the visualization can be changed by passing it an instance of an equivalent, but different UI
This requires no change in the code of the visualization • This can be accomplished by making the new UI a subclass of the old one • You can always pass in a subclass object when the parameter is typed to a superclass
The book continues the example by naming the subclass of UI BetaUI • The requirements for BetaUI are these: • The image should a cherry instead of a rocket • The font should be italic • On the next overhead, partial code for BetaUI is given
public class BetaUI extends UI • { • public BetaUI() • { • Font oldFont = getFont(); • font = new Font( • oldFont.getName(), • oldFont.getStyle() | Font.ITALIC, • oldFont.getSize()); • } • /* Notice that the plan is to make use of the superclass as much as possible. However, something somewhat devious may be going on here. The font instance variable is inherited. Its characteristics are being changed in the subclass. Is an instance variable being overridden? */
public JButtoncreateButtonOk() • { • // Challenge! • } • public JButtoncreateButtonCancel() • { • // Challenge! • } • }
Challenge 17.1 • Complete the code for the BetaUI class.
Solution 17.1 • One solution is as follows: • [See the following overheads.]
public JButtoncreateButtonOk() • { • JButton b = super.createButtonOk(); • b.setIcon(getIcon(“images/cherry-large.gif”)); • return b; • } • public JButtoncreatButtonCancel() • { • Jbutton b = super.createButtonCancel(); • b.setIcon(getIcon(“images/cherry-large-down.gif”)); • return b; • } • This code takes the approach of using the base class methods as much as possible.
The book illustrates how this works by giving the following code which uses the BetaUI class instead of the UI class • public class ShowBetaVisualization • { • public static void main(String[] args) • { • Jpanel panel = new Visualization(new BetaUI)); • SwingFacade.launch(panel, “Operational Model”); • } • }
The book states that this example illustrates the usefulness of the design pattern • However, it also states that the example has some shortcomings • The shortcomings will be listed below • After that the book will suggest an alternative design
One of the stated shortcomings is that, as written, the BetaUI class depends on the ability to override the creation methods • It certainly seems up to this point that this was done intentionally • Based on this observation alone, it’s not clear how this is a shortcoming • It remains to be seen whether or how an alternative would avoid this
Another shortcoming, as stated by the book • The subclass methods need access to protected instance variables, like font, from the superclass • First of all, I’m not a fan of the protected modifier • Whether you use it or not, you still should have access with get and set methods • It will not be clear exactly what the book means until its alternative is presented • For the time being it’s not clear whether it’s hinting at the “overriding an instance variable” problem,
Challenge 17.2 • Suggest a design change that would still allow for the development of a variety of GUI control factories but that would reduce the reliance of subclasses on method modifiers in the UI class. • Comment mode on: • As usual, there’s no reason to try and predict what the book will do until you see it. • However, once you do see it, it will be clear that it was a simple application of something you know.
Solution 17.2 • One solution for producing a more resilient design would be to specify the expected creation methods and standard GUI properties in an interface, as Figure B.20 shows. • [See the next overhead.]
Comment mode on: • I’m not convinced • If BetaUI implemented the interface instead of extending UI, I can see how their goals might be accomplished • As it is, structuring the application in this way might be a design convenience, but it’s not so clear that it solves the identified problems
Since interface methods are public by default, you’ve forced public methods, but you could have done that in the UI class anyway • As for the instance variables, if each class implemented the interface, each would have to provide the needed variables • As shown, BetaUI would still inherit instance variables from UI and “override” them
It may be that I just misunderstand what the book is trying to say • On the other hand, maybe there is a mistake in the diagram provided in the book
Maybe both UI and BetaUI were supposed to separately implement the GuiFactory interface • If so, such a design would approach the alternative that I mentioned at the beginning • It would not be very different from having an abstract GuiFactory class with both UI and BetaUI as concrete subclasses