Unit 22 Abstract Factory

Post on 23-Mar-2016

35 views 1 download

Tags:

description

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 - PowerPoint PPT Presentation

Transcript of Unit 22 Abstract Factory

1

Unit 22Abstract Factory

Summary prepared by Kirk Scott

2

Design Patterns in JavaChapter 17

Abstract Factory

Summary prepared by Kirk Scott

3

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

4

• Book definition:• The intent of the Abstract Factory, or Kit, is to

allow creation of families of related or dependent objects.

5

• 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

6

• 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

7

• 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

8

• 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

9

• 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

10

• 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

11

• 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

12

• 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

13

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

14

• 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

15

16

• Before going any further, observe the following:• It might be a better illustration of the pattern

overall if there were an abstract superclass AbstractUI

• 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

17

• 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

18

19

• 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

20

21

• 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

22

23

• The UML diagram for the UI class showed these methods: – createButton(), – getFont(), – createPaddedPanel(), – and getIcon()

24

• 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

25

• public JButton createButton()• {• JButton button = new JButton();• button.setSize(128, 128);• button.setFont(getFont());• button.setVerticalTextPosition(AbstractButton.BOTTOM);• button.setHorizontalTextPosition(AbstractButton.CENTER);• return button;• }

26

• public JButton createButtonOk()• {• JButton button = createButton();• button.setIcon(getIcon(“images/rocket-large.gif”));• button.setText(“Ok!”);• return button;• }

27

• public JButton createButtonCancel()• {• JButton button = createButton();• button.setIcon(getIcon(“images/rocket-large-down.gif”));• button.setText(“Cancel!”);• return button;• }

28

• 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

29

• 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

30

• 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

31

• protected JButton undoButton()• {• if(undoButton == null)• {• undoButton = ui.createButtonCancel();• undoButton.setText(“Undo”);• undoButton.setEnabled(false);• undoButton.addActionListener(mediator.undAction());• }• return undoButton;• }

32

• 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

33

• 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

34

• 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

35

• 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? */

36

• public JButton createButtonOk()• {• // Challenge!• }• public JButton createButtonCancel()• {• // Challenge!• }• }

37

• Challenge 17.1• Complete the code for the BetaUI class.

38

• Solution 17.1• One solution is as follows:• [See the following overheads.]

39

• public JButton createButtonOk()• {• JButton b = super.createButtonOk();• b.setIcon(getIcon(“images/cherry-large.gif”));• return b;• }• public JButton creatButtonCancel()• {• 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.

40

• 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”);• }• }

41

• 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

42

• 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

43

• 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,

44

• 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.

45

• 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.]

46

47

• 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

48

• 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

49

• 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

50

• 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

51

• Comment mode off; back to topics in the book• The book observes that in a sense an abstract

factory class is like a collection of factory methods

• Recall that a factory method was not just a method

• It was an arrangement of classes and a method that returned a reference to an object

52

• The goal was to have a client call the method and receive back a reference to an object that implemented a given interface

• The client didn’t have to know exactly what kind of object was returned to it

• It was simply necessary that the object implemented the interface and agreed with type required by the client

53

Abstract Factories and Factory Method

• The book has several examples and challenges• From my point of view, the presentation is

somewhat garbled and this makes it more difficult to see the pattern

• The remaining overheads for this chapter may be in book order in some places

• In other places, they may be rearranged and the explanations adjusted to fit my understanding of what’s going on

54

• One of the reasons the presentation gets messy is that the book wants to separate classes into packages

• This isn’t a bad idea, and it’s a topic that isn’t covered in CS 201 and 202

• It also hasn’t really been addressed in CS 304

55

• However, the book starts dividing things up into packages at the same time it’s developing the example

• The final subsection in the chapter is about packages

• By the time you get to that section, most of what’s going to be done has already been done without very clear explanations

56

Factory Methods and Abstract Factory

• The first thing to note about the next example is that its built on the factory method example

• In other words, an abstract factory can be described as a class containing a collection of factory methods

57

• You may realize that you would like to apply the abstract factory pattern when several related factory methods arise in an application design

• The idea is that there is a group of related objects that need to be created and you put the methods for creating them together in a common class

58

• Here is a thumbnail review of the factory method example

• The CreditCheckFactory has a method createCreditCheck() that returns a reference to an object that implements the CreditCheck interface

• Two classes, CreditCheckOnline and CreditCheckOffline implement the interface

59

• The code of the createCreditCheck() method knows which kind of object to create based on “server” code conditions

• Client code will receive a reference to one of the two different kinds of objects

• Client code doesn’t have to to specify or care which kind of object comes back

• The UML diagram for this is given on the next overhead

60

61

• The book now adds things called billing checks and shipping checks to the credit check example

• It doesn’t really explain what these things are, but it’s apparent that as checks, they are classified with credit checks

62

• An intermediate UML diagram is given on the next overhead

• It introduces the idea that you can start putting related things together in packages

• The diagram is intermediate because it doesn’t have enough information in it to show how it illustrates the abstract factory design pattern

• Specific comments on that will follow the diagram

63

64

• In the preceding diagram there were two new classes, ShippingCheck and BillingCheck

• Although they are checks of some sort, they don’t seem to be new types of credit checks

• They don’t implement the CreditCheck interface

65

• Not surprisingly then, the CreditCheckFactory doesn’t have a method which constructs objects of these two new classes

• So the question remains, what are they exactly, and what role will they play in the abstract factory design pattern?

66

• Another UML diagram is given on the following overhead

• This is the book’s next step in explaining the design pattern—but it still doesn’t give the whole picture

• In this diagram, the checks have become interfaces• Also, the CreditCheckFactory includes methods

that return values that are of the types billing check, shipping check, and credit check

67

68

• The preceding overhead was a UML diagram of the com.oozinoz.credit package, which contained these elements:– A CreditCheck interface– A CreditCheckOffline class that implements the

interface– Two more interfaces, BillingCheck and ShippingCheck– A CreditCheckFactory class containing methods to

create instances of each kind of check

69

• Although it’s not possible to change what the book has done, it is worth noting the following:

• In some sense, the example might be clearer and better if the CreditCheckFactory class were abstract

• This class turns out to be the “abstract” factory in the design being developed

70

• Also notice that the design could not be fully functional as given so far

• The return types for the methods of the CreditCheckFactory class are simply interface definitions

• No actual check classes are shown that could be constructed and returned

71

• The book brings the example to completion in more or less the following way:

• There will be no direct instances of the CreditCheckFactory class in the credit package

• There will be other packages, one for each country, such as the U.S. or Canada

72

• In these packages there will be classes that implement the interfaces in the credit package

• There will also be a factory class which extends the CreditCheckFactory class in the credit package

• The next overhead illustrates the relationship between the credit package and the Canada package

73

74

• The Canada package contains live classes BillingCheckCanada, ShippingCheckCanada, and CreditCheckCanadaOnline which implement the check interfaces

• The package contains the CheckFactoryCanada class which extends the CreditCheckFactory class

• The contents of the CheckFactoryCanada class aren’t shown in detail in this diagram

• However, it will either inherit or override the methods which return either a billing check, a shipping check, or a credit check

75

• Comment mode on:• As noted earlier, I think the example would be

better if the CreditCheckFactory class were abstract

• I also think it would be better if that class were renamed simply CheckFactory

• Billing and shipping checks don’t seem to be kinds of credit checks, but methods to create them are included in the factory

76

• CreditCheckFactory only has the name it does because it was named before the example was expanded

• Notice that the subclass is named CheckFactoryCanada, not CreditCheckFactoryCanada

• In other words, implicitly the authors recognize that at the implementation level this is a check factory, not a credit check factory

• Also, if you read the text closely, you’ll discover that at one point the authors refer to the CheckFactoryCanada class as a concrete factory, not an abstract factory

77

Continuing to Outline the Example

• No separate package is given for the U.S., but conceptually the example is set up as if there would also be a concrete package for the U.S., analogous to the Canada package

• If set up as I would set it up, the credit package would contain an abstract check factory class and the two other packages would each contain a concrete check factory class that extended it

78

• There is a reason that the CreditCheckOffline class in the credit class already is a concrete class that implements the CreditCheck interface

• The CreditCheckOffline is going to be the same for both Canada and the U.S. and can be shared by the code for both

• That can be taken care of with one implementing class in the parent package

79

• The book says that the abstract factory pattern is like a collection of factory methods

• It is after the U.S. package is added to the picture that this becomes apparent

• Take just createBillingCheck() for example

80

• The return type of createBillingCheck() in the Canada package implementation will be BillingCheck

• There would also be a separate implementation of the method in the U.S. package

• It would also return an object of type BillingCheck

81

• Not only is the factory method at work because there are two kinds of credit check, online and offline

• The factory method is also at work because there are two kinds of billing check, Canadian and American

• There are different classes for each, but they both implement the common BillingCheck interface

82

• There could be an additional layer of code on the server side of the example

• That layer would contain if/else logic to determine whether a customer that a billing check was being run on was Canadian or American

• In other words, there might be a method whatKindOfCustomer() in this example

• That would be analogous to isAgencyUp() in the factory method example of the previous chapter

83

• The actual kind of billing check object returned to a client would depend on the outcome of a call to whatKindOfCustomer()

• The ultimate client code would simply be handed a reference to an object that implemented the BillingCheck interface

• The client wouldn’t have to be aware or specifically request a billing check for one country or the other

84

The Implementation of the CheckFactoryCanada Class

• Examining the code clarifies to a degree what is going on• The only concrete method that would be necessary in the

CreditCheckFactory class of the credit package would be isAgencyUp()

• The implementations of the methods in the CreateCheckCanada class that create checks would be country specific and override methods of the same name in the CreditCheckFactory class

• This is further evidence that the superclass should be abstract…

85

• The book presents writing the code for CreateCheckCanada as challenge 17.4

• The complete code is given on the following overheads

86

• package com.oozinoz.ca;• import com.oozinoz.credit.*;• public class CheckFactoryCanada extends CheckFactory• {• public BillingCheck createBillingCheck()• {• return new BillingCheckCanada();• }• public CreditCheck createCreditCheck()• {• if(isAgencyUp())• return new CreditCheckCanadaOnline();• return new CreditCheckOffline();• }• public ShippingCheck createShippingCheck()• {• return new ShippingCheckCanada();• }• }

87

• Solution 17.4, book stuff continued• Your solution should• Implement create- methods for methods

inherited from the abstract CreditCheckFactory class

• Comment mode on:• This indicates again what has gone wrong with

the book example: They didn’t show that class and its methods as abstract in the UML diagram

88

• Solution 17.4, book stuff continued• [Your solution should]• Have the proper interface for the return type

of each create- method• Return a CreditCheckOffline object if the

agency is down• Comment mode on:• This is obvious from the code already shown…

89

The UI Example vs. the Credit Check Example

• After all this, if you’re still following my attempt to explain why the book’s presentation is muddled, consider these points

• In the UI example they had a concrete UI superclass for a given “standard” interface

• Then they added a concrete BetaUI subclass for an alternative interface

90

• There was no literally abstract factory class in that example

• It might have been better if they had had an abstract superclass with two concrete subclasses, UI and BetaUI

91

• In the current, credit check example, they claim that there would be three packages: the credit package, the Canadian package, and a U.S. package

• They only show things for the credit and Canadian package

92

• The credit package contains a concrete class, not an abstract class

• This is what I think they did, probably unintentionally

• They started with a package that would have worked for the U.S. alone

• It would have contained concrete classes for shipping, billing, and credit checks

• It also would have contained a concrete factory class

93

• In other words, the credit/U.S. factory class would have been analogous to the UI class in the previous example

• Then the Canadian factory class would have been analogous to the BetaUI class in the previous example

• They started changing over and only got halfway

94

• They changed the checks to interfaces, but they left the concrete check factory (with its old name) in place

• If this explanation is correct, it’s understandable how the mix-up could occur

• Unfortunately, it makes things overall harder to sort out

95

• Final note on this topic:• At one point in the previous materials the book

referred to the CreateCheckCanada class as a concrete factory

• By the end of the chapter it’s back to referring to the pattern overall as abstract factory

• And as a consequence, even though the class in the Canadian package was concrete, it is referred to as an abstract factory class

96

Packages and Abstract Factories

• The book now returns to the question of packages

• What more they actually have to say about packages is contained in the next challenge

97

• Challenge 17.5• Write down an argument supporting the

decision to place each factory and its related classes in a separate package.

• Or, argue that another approach is superior.

98

• Solution 17.5• An example justification is:• Placing country-specific classes in separate

packages helps our Oozinoz developers to organize our software and our development efforts.

• By placing the classes for each country in a separate package, we keep country-specific packages independent of one another.

99

• We can be confident, for example, that U.S.-specific classes have no impact on Canada-specific classes.

• We can also easily add support for new countries.

• For example, when we start doing business with Mexico, we can create a new package that provides the check services we need in a way that makes sense in that country.

100

• This has the further advantage of letting us assign the credit.mx package to a developer who has expertise in working with services and data from Mexico.

101

• An argument against:• Although this separation is nice in theory, it’s

overwrought in practice.• I’d rather have only one package with all the classes in it,

at least until we expand to nine or ten countries.• Spreading these classes over multiple packages winds

up causing me three or more times the configuration-management work when I need to implement a change that cuts across all these packages.

102

• Comment mode on:• Eventually, as software grows, you may start

to use packages• If so, you’ll have to decide how to divide them

up.• When the time comes, you’ll have to make

your own decision about the right approach

103

Summary

• What follows is a fairly faithful summary of what the book includes in the summary, interspersed with commentary

• The Abstract Factory pattern lets you arrange for a client to create objects that are part of a family of related dependent objects

• Comment mode on:• It is clear from the examples that the objects are related• The book hasn’t explained specifically what it means

when it now says that they’re dependent

104

• One example of related objects is groups of objects for different GUIs

• Another example of related objects is groups of objects for different countries

105

• As with Factory Method, Abstract Factory isolates clients from knowing which class to instantiate.

• Comment mode on:• This can be true, but the examples in this chapter

didn’t grow to the point of illustrating it specifically

• For example, there was no server side code that checked which country a check request was being made for

106

• Comment mode, continued:• Going back to the earlier example there was just one

example of using an abstract factory• It contained this call:• JPanel panel = new Visualization(new BetaUI());

• Whatever else you might say, it’s clear that this code had to specify which UI to use

• The only question is whether code of this form would appear on the client side or on the server side of the application overall

107

• Comment mode, continued:• No example client code was given for the Canadian

credit check example• However, the situation is analogous to the previous

one• At some point a CheckFactoryCanada object would

have to be created so that the unique implementations of the methods in it could be called

• The question is whether the creation of the object would be in client code or in server code

108

The End