html5-img
1 / 88

Unit 20 Factory Method

Unit 20 Factory Method. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 16 Factory Method. Summary prepared by Kirk Scott. Ordinary construction relies on the existence of constructors in a base class

zelda
Télécharger la présentation

Unit 20 Factory Method

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Unit 20Factory Method Summary prepared by Kirk Scott

  2. Design Patterns in JavaChapter 16Factory Method Summary prepared by Kirk Scott

  3. Ordinary construction relies on the existence of constructors in a base class • The Factory Method design pattern still relies on these ordinary constructors • However, it protects the client from using the constructors directly

  4. The client code can be written so that all it cares about is that the objects it works with implement a given interface • The client code may work with several different base classes • The client code may not know or care specifically which kind of object it is working with • Dynamic binding makes this practical

  5. A base class will implement a factory method which returns an object of a given interface • The actual type of the underlying object returned to the client will depend on the logic internal to the factory method • The client will not be in control of the actual type of object that it receives

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

  7. A Classic Example: Iterators • Iterators were introduced earlier as an independent design pattern • I observed that in a sense, they were simple examples of the template pattern • Iterators also illustrate the idea behind the factory method • The later example will be structured somewhat differently, but by intent, the iterator() method serves as a kind of factory for iterator objects

  8. Iteration is built on top of the idea of a collection class • 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 over elements of the given collection

  9. The iterator() method returns something that implements the Iterator interface • When you call iterator() on an object of a given collection class, an iterator for that class is returned • When you call iterator() on an instance of another collection class, an iterator for that class is returned • The iterator() method is the factory method

  10. The client doesn’t have to “know” specifically what kind of iterator is being returned • The returned object simply has to implement the Iterator interface • That allows the client to call the methods defined in that interface on the returned object

  11. Code with an Iterator • The book pursues this idea with an example • The code on the following overhead illustrates the creation and use of an iterator for a collection of type List • The instance of List is constructed by hard coding a simple array of strings and passing it in to the List object

  12. import java.util.*; • public class ShowIterator • { • public static void main(String[] args) • { • List list = Arrays.asList( • new String[] { "fountain", "rocket", "sparkler" }); • Iteratoriter = 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()); • } • }

  13. Challenge 16.1 • What is the actual class of the Iterator object in this code?

  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());

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

  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.

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

  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.

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

  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 those methods

  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.

  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 • You have no way of knowing this unless you’re already familiar with the BorderFactory class

  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.

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

  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

  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

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

  28. 3. Make a CreditCheckFactory class with a createCreditCheck() method that returns an object of type CreditCheck • In this example the question is, what kind of credit limit is it, an online or offline one? • The createCreditCheck() method will return a reference to one kind of object or another • createCreditCheck() is the factory method

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

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

  31. Comment mode on: • I’m not overwhelmed by the UML diagram. • It would be more helpful if it showed a link between the factory and the interface, indicating that the factory makes use of the interface • It would also be more helpful if it showed a client which used the factory to obtain a reference to an object that implemented the interface

  32. The Builder UML is repeated on the next overhead • What I have in mind is that the client is the client • The builder is roughly equivalent to the class containing the factory method • The base class is roughly equivalent to the factory interface • The implementing classes aren’t shown, but they would descend from the base class/interface

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

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

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

  36. 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().

  37. 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 CreditCheckcreateCreditCheck() • { • if(isAgencyUp()) • return new CreditCheckOnline(); • return new CreditCheckOffline(); • }

  38. Comparing the Factory Method and Strategy Patterns • Compare the factory method pattern with the previous pattern, strategy • In strategy, the client code included the logic to decide which kind of strategy object to use • In factory method, it is the service code that contains the (if) logic to decide which kind of object to return • The decision is made based on conditions unknown to or extraneous to the client

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

  40. The book illustrates this with machines and machine managers in a fireworks factory • 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

  41. 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 functionality for managing availability

  42. More background information includes the following: • getAvailable() is supposed to forecast when a machine will finish its current work and become available • getAvailable() will be implemented in planner classes that parallel the machine classes • Most machine types will have different logic, requiring different kinds of planner (classes) • Mixers and fusers can share the same kind of planner (class)

  43. Challenge 16.6 • Fill in the diagram of a Machine/MachinePlanner parallel hierarchy in Figure 16.3.

  44. Solution 16.6 • Figure B.19 shows a reasonable diagram for the Machine/MachinePlanner parallel hierarchy.

More Related