Factory method, strategy pattern & chain of responsibilities
Unit 21 Factory Method
description
Transcript of Unit 21 Factory Method
![Page 1: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/1.jpg)
1
Unit 21Factory Method
Summary prepared by Kirk Scott
![Page 2: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/2.jpg)
2
Design Patterns in JavaChapter 16
Factory Method
Summary prepared by Kirk Scott
![Page 3: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/3.jpg)
3
• Ordinary construction relies on the existence of constructors in a base class
• The Factory Method design pattern also relies on these ordinary constructors
• The idea is that client code may not know or care specifically which kind of object it is working with
• What it cares about is that the object implements a desired interface
![Page 4: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/4.jpg)
4
• Suppose the client works with several different base classes
• Each of these base classes, in turn, may rely on/create instances of different underlying classes, which the client needs an instance of
• Each of the base classes will implement a factory method which returns an object of a given interface
• The underlying classes all implement that interface• The actual type of the underlying object returned to the
client will depend on the logic of the particular base class that implements the factory method
![Page 5: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/5.jpg)
5
• Book definition:• The intent of the Factory Method is to let a
class developer define the interface for creating an object while retaining control of which class to instantiate.
![Page 6: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/6.jpg)
6
A Classic Example: Iterators
• Iterators provide a way to access the elements of a collection sequentially
• There is a Collection interface• Every class that implements the Collection
interface has to implement the method iterator()
• The iterator() method returns an instance of an iterator
![Page 7: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/7.jpg)
7
• In this example, the Collection interface is not “the” interface of the Factory Method design pattern
• The Collection interface is simply the mechanism that makes sure that every implementing class has an iterator() method
• The iterator() method is the factory method
![Page 8: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/8.jpg)
8
• The point is this:• You can call iterator() on any collection class• The iterator() method returns something that
is typed Iterator• However, Iterator is not a class• Iterator is an interface
![Page 9: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/9.jpg)
9
• The class of the object returned by a call to the iterator() method differs according to which kind of object it was called on
• The iterator() method could be called on an ArrayList and the type of the actual object returned would be an iterator for an ArrayList
• The iterator() method could be called on a HashMap and the type of the actual object returned would be an interator for a HashMap
![Page 10: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/10.jpg)
10
• The client code doesn’t care what the actual type of object is
• Formally, it only cares that it be typed Iterator• Functionally, this means that the client code
can call on any iterator any of the methods defined in the Iterator interface
• The client code does not need to be able to call any class specific methods, if they even exist
![Page 11: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/11.jpg)
11
• The code on the following overhead illustrates the creation and use of an iterator for a collection of type List
• The List itself is constructed by hard coding a simple array of strings and passing it in to the List object
![Page 12: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/12.jpg)
12
• import java.util.*;• public class ShowIterator • {• public static void main(String[] args) • {• List list = Arrays.asList(• new String[] { "fountain", "rocket", "sparkler" });• • Iterator iter = list.iterator();• • while (iter.hasNext()) • System.out.println(iter.next());• • // Uncomment the next line • // to see the iterator's actual class:• // System.out.println(iter.getClass().getName());• }• }
![Page 13: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/13.jpg)
13
• Challenge 16.1• What is the actual class of the Iterator object
in this code?
![Page 14: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/14.jpg)
14
• Solution 16.1• A good answer, perhaps, is that you do not need to
know what class of object an iterator() method returns.
• What is important is that you know the interface that the iterator supports, which lets you walk through the elements of a collection.
• However, if you must know the class, you can print out its name with a line like:
• System.out.println(iter.getClass().getName());
![Page 15: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/15.jpg)
15
• This statement prints out:• java.util.AbstractList$Itr• The class Itr is an inner class of AbstractList.
You should probably never see this class in your work with Java.
• [End of Solution 16.1.]
![Page 16: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/16.jpg)
16
Recognizing Factory Method
• There are many methods floating around object-oriented code which return references to newly created objects of one class or another
• Just because a method returns such a reference doesn’t mean that it implements the Factory Method design pattern.
![Page 17: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/17.jpg)
17
• Challenge 16.2• Name two commonly used methods in the
Java class libraries that return a new object.• [And don’t implement the Factory Method
design pattern.]
![Page 18: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/18.jpg)
18
• Solution 16.2• There are many possible answers, but
toString() is probably the most commonly used method that creates a new object.
• For example, the following code creates a new String object:
• String s = new Date().toString();
• The creation of strings often happens behind the scenes.
![Page 19: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/19.jpg)
19
• Consider:• System.out.println(new Date());• This code creates a String object from the Date
object, ultimately by calling the toString() method of the Date object.
• Another frequently used method that creates a new object is clone(), a method that usually returns a copy of the receiving object.
• [End of Solution 16.2.]
![Page 20: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/20.jpg)
20
• The point of the answers to the previous challenge is this:
• toString() and clone() don’t exhibit the Factory Method design pattern
• They don’t protect the client (the calling code) from knowing what kind of object is being constructed and returned
• There is no set of classes under the covers that implement a common interface which is the type returned by the calls to the methods
![Page 21: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/21.jpg)
21
• Challenge 16.3• The class javax.swing.BorderFactory sounds
like it ought to be an example of the Factory Method pattern.
• Explain how the intent of the Factory Method pattern is different from the intent of the BorderFactory class.
![Page 22: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/22.jpg)
22
• Comment mode on:• This challenge basically boils down to a red
herring• It’s like asking whether the so-called Adapter
classes in Java implement the Adapter design pattern
• The answer is no, it’s just the use of the same word to mean a different thing
![Page 23: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/23.jpg)
23
• Solution 16.3• The intent of the Factory Method pattern is to
let an object provider determine which class to instantiate when creating an object.
• By comparison, clients of BorderFactory know exactly what object types they’re getting.
• The pattern at play in BorderFactory is Flyweight, in that BorderFactory uses sharing to efficiently support large numbers of borders.
![Page 24: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/24.jpg)
24
• The BorderFactory class isolates clients from managing the reuse of objects, whereas Factory Method isolates clients from knowing which class to instantiate.
• [End of Solution 16.3.]
![Page 25: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/25.jpg)
25
Taking Control of Which Class to Instantiate
• The book now moves on from examples like iterator(), which already exist in Java
• It paints a scenario where client code needs to obtain a credit limit for a customer
• If a credit agency is online, then the credit limit is generated with an instance of a class named CreditCheckOnline
![Page 26: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/26.jpg)
26
• If the credit agency is offline, then the credit check is generated with an instance of a class named CreditCheckOffline
• The method that the client code is going to call is creditLimit()
• The client code doesn’t care exactly what kind of object is returned
• The UML diagram on the following overhead illustrates the situation so far
![Page 27: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/27.jpg)
27
![Page 28: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/28.jpg)
28
• The key point of this example is that we’re one step lower down in the implementation details than we were in the iterator example
• In the iterator example, the iterator() method was simply a given for each class that implemented the Collection interface
• If you called iterator() on an object, it returned an instance of the right kind of iterator
![Page 29: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/29.jpg)
29
• In this example, the CreditCheckOnline and the CreditCheckOffline classes are roughly analogous to the different types of iterator
• When this example is fully worked out, there will be another class which contains the factory method
• When the factory method is called on an instance of that class, it will determine whether to construct an instance of CreditCheckOnline or CreditCheckOffline
![Page 30: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/30.jpg)
30
• The book outlines these elements of an application of the Factory Method design pattern to this situation:
• 1. Make a CreditCheck interface that includes a creditLimit() method
• 2. Have the classes CreditCheckOnline and CreditCheckOffline implement this interface
![Page 31: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/31.jpg)
31
• 3. Make a CreditCheckFactory class with a createCreditCheck() method that returns an object of type CreditCheck
• When you first look at these classes, it may be tempting to think that the creditLimit() method in the two base classes is analogous to the iterator() method in the foregoing example
• In other words, you might think that the creditLimit() method is the factory method
![Page 32: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/32.jpg)
32
• However, this is not the case• The creditLimit() method returns a reference,
to an instance of Dollars• This is practically the same as returning a
simple type• More importantly, both implementations of
creditLimit() return the same type of thing
![Page 33: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/33.jpg)
33
• There is no choice there of what to create• The creditLimit() method is analogous to the
hasNext() method in the Iterator interface• hasNext() can be called on any object that
implements the Iterator interface
![Page 34: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/34.jpg)
34
• In the iterator example the overarching question is, what kind of iterator is it, an ArrayList iterator, a HashMap iterator?
• In this example the question is, what kind of credit limit is it, an online or offline one?
• It is the method createCreditCheck() that returns a reference to one kind of object or another
• It is this method that is the factory method
![Page 35: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/35.jpg)
35
• Challenge 16.4• Draw a class diagram that establishes a way
for this new scheme to create a credit-checking object while retaining control of which class to instantiate.
![Page 36: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/36.jpg)
36
• Solution 16.4• Figure B.18 shows that the two credit check
classes implement the CreditCheck interface.• The factory class provides a method that
returns a CreditCheck object.• The client that calls createCreditCheck() does
not know the precise class of the object it receives.
![Page 37: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/37.jpg)
37
![Page 38: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/38.jpg)
38
• Solution 16.4, continued• The createCreditCheck() method is a static
method, so clients need not instantiate the CreditCheckFactory class in order to get a CreditCheck object.
• You can make this class abstract or give it a private constructor if you want to actively prevent other developers from instantiating it.
• [End of Solution 16.4.]
![Page 39: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/39.jpg)
39
• Once again, this is the basic idea of the example:• Client code doesn’t know whether credit checking
is available online or offline• It simply wants a credit check generated• It does this by calling createCreditCheck()• The logic of the code for that method determines
which kind of actual credit check object is returned• However, whatever is returned, it will implement
the CreditCheck interface
![Page 40: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/40.jpg)
40
• Challenge 16.5• Assume that the CreditCheckFactory class has
an isAgencyUp() method that tells whether the credit agency is available, and write the code for createCreditCheck().
![Page 41: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/41.jpg)
41
• Solution 16.5• If you take a leap of faith that the static method
isAgencyUp() accurately reflects reality, the code for createCreditCheck() is simple:
• public static CreditCheck createCreditCheck()• {• if(isAgencyUp())• return new CreditCheckOnline();• return new CreditCheckOffline();• }
![Page 42: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/42.jpg)
42
Factory Method in Parallel Hierarchies
• Given a hierarchy of classes, you may decide to move a subset of behavior out of the classes and implement it in separate classes
• The result is a parallel hierarchy of classes• The Factory Method design pattern can arise
in such a situation
![Page 43: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/43.jpg)
43
• The book illustrates this with machines and machine managers in a fireworks factory
• The example is not exactly the same, but you may notice similarities with the material presented in the chapter on the Bridge pattern
• The UML diagram on the next overhead gives the starting point for the example
• There are various concrete types of machine that extend the abstract Machine class
![Page 44: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/44.jpg)
44
![Page 45: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/45.jpg)
45
• The scenario is that you would like to have a getAvailable() method for machines for planning purposes
• However, the logic for implementing getAvailable() is relatively complex
• A parallel hierarchy arises when you decide to factor out the management functionality
![Page 46: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/46.jpg)
46
• More background information includes the following:
• getAvailable() is supposed to forecast when a machine will finish its current work and become available
• Most machine types will have different logic, requiring different kinds of planner (classes)
• Mixers and fusers are simple and quick enough that the are essentially always available and they can share the same kind of planner (class)
![Page 47: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/47.jpg)
47
• Challenge 16.6• Fill in the diagram of a
Machine/MachinePlanner parallel hierarchy in Figure 16.3.
![Page 48: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/48.jpg)
48
![Page 49: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/49.jpg)
49
• Solution 16.6• Figure B.19 shows a reasonable diagram for
the Machine/MachinePlanner parallel hierarchy.
![Page 50: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/50.jpg)
50
![Page 51: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/51.jpg)
51
• Solution 16.6 continued• This diagram indicates that subclasses of MachinePlanner
must implement the getAvailable() method.• The diagram also indicates that classes in the
MachinePlanner hierarchy accept a Machine object in their constructors.
• This allows the planner to interrogate the object it is planning for, regarding such criteria as the machine’s location and the amount of material it is currently processing.
![Page 52: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/52.jpg)
52
• Notice that the discussion so far hasn’t quite made it clear how the Factory Method design pattern fits into the picture
• The book now addresses that question by means of a challenge
![Page 53: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/53.jpg)
53
• Challenge 16.7• Write a createPlanner() method for the
Machine class to return a BasicPlanner object, and write a createPlanner() method for the StarPress class
![Page 54: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/54.jpg)
54
• Comment mode on:• Don’t be confused by the reference arrows in
the UML diagram• When an object of a machine class creates a
planner, it passes the planner a reference to itself
• However, construction of planners happens on the machine side of the hierarchy
![Page 55: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/55.jpg)
55
• Each kind of machine knows what kind of planner to create for itself
• The Factory Method pattern results from the fact that the actual machines extend the abstract Machine class
• Each concrete machine class implements the createPlanner() method
• This is the factory method
![Page 56: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/56.jpg)
56
• Client code makes calls of the form someMachine.createPlanner()
• All the client code cares about is that the return value is of the MachinePlanner interface type
• The client is not concerned with which actual type of planner object is returned
![Page 57: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/57.jpg)
57
• Solution 16.7• A createPlanner() method for the Machine
class might look like:• public MachinePlanner createPlanner()• {• return new BasicPlanner(this);• }
![Page 58: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/58.jpg)
58
• The Fuser and Mixer classes can rely on inheriting this method, whereas the ShellAssembler and StarPress class will need to override it.
• For the StarPress class, the createPlanner() method might be:
• public MachinePlanner createPlanner()• {• return new StarPressPlanner(this);• }
![Page 59: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/59.jpg)
59
• These methods show the Factory Method pattern at work.• When we need a planner object, we call the
createPlanner() method of the machine we want a planner for.
• The specific planner that we receive depends on the machine.
• It’s analogous to the iterator example• We ask for an iterator on a collection class object and
don’t care exactly what kind of iterator it is as long as it implements the Iterator interface
![Page 60: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/60.jpg)
60
Summary
• The Factory Method design pattern allows client code not to know exactly what kind of object is going to be created
• On the factory side, each different kind of object has to implement the same interface
• Then the client is only concerned that the returned object be of the type of the interface
![Page 61: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/61.jpg)
61
• The book illustrated the idea by noting how the iterator() method works in the Java API
• It illustrated a case where the client code would not know which kind of object to construct with the credit example
• It also brought out that the design pattern can be useful with parallel hierarchies where the client only needs to know the one hierarchy and the interface for the other
![Page 62: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/62.jpg)
62
• Comment mode on for the last time in this chapter:
• It seems that in the given parallel hierarchies example, it was the slight mismatch between the hierarchies that motivated the use of the pattern
![Page 63: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/63.jpg)
63
• If the hierarchies matched exactly, the client, in theory at least, would know:
• If I want to construct a planner for and instance of MachineX
• Then I can expect back from construction, whether ordinary or through a factory method, an instance of PlannerX
![Page 64: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/64.jpg)
64
• However, the same observation is true of the iterator example
• If every different collection class has its own iterator type
• Then in theory, client code would know what kind of iterator it was getting
• But the point is that the client code shouldn’t have to worry about this
• And it doesn’t have to when the Factory Method design pattern is applied
![Page 65: Unit 21 Factory Method](https://reader036.fdocuments.us/reader036/viewer/2022062422/56813a23550346895da2011c/html5/thumbnails/65.jpg)
65
The End