Presentation is loading. Please wait.

Presentation is loading. Please wait.

Unit 6 Proxy Summary prepared by Kirk Scott 1. Design Patterns in Java Chapter 11 Proxy Summary prepared by Kirk Scott 2.

Similar presentations


Presentation on theme: "Unit 6 Proxy Summary prepared by Kirk Scott 1. Design Patterns in Java Chapter 11 Proxy Summary prepared by Kirk Scott 2."— Presentation transcript:

1 Unit 6 Proxy Summary prepared by Kirk Scott 1

2 Design Patterns in Java Chapter 11 Proxy Summary prepared by Kirk Scott 2

3 The Introduction Before the Introduction The chapter on the Proxy design pattern in the book is not ideal It is broken into four different parts 1. An illustration of the design pattern for image loading After explaining the example, the book states that although it illustrates the pattern, the resulting design is not desirable 3

4 2. The book then refactors the bad design into something it considers better. It refers to this design as being a proxy in spirit but not in structure As a consequence, it’s not clear whether the second example should stick in your mind as an illustration of the concepts involved or whether the first example is better because it is structurally closer 4

5 3. The book then considers the use of what it calls remote proxies Proxies can definitely be useful in this environment However, writing code that is distributed on different hardware platforms is beyond the scope of this course Therefore, this section of the chapter will only be covered in passing 5

6 4. The last section of the chapter concerns dynamic proxies This is also a useful application area for the design pattern However, it is not necessarily a frequently occurring application Like the previous section, this will only be covered in passing 6

7 Beginning of Book Material Customary apportionment of responsibility in a design means that every class is responsible for implementing the code necessary to support its public interface (interface in the generic, non-Java sense) As with the other responsibility patterns, the Proxy design pattern is used in cases where the customary treatment of responsibility isn’t appropriate or can be improved upon 7

8 The book outlines three examples where this might be the case: 1. When the base object might take too long to load 2. When the base object is on another computer 3. When you would like to intercept method calls to a base object so that you can wrap the underlying call to that object with code of your own 8

9 In those cases a software design might include a proxy class A proxy object stands in for a base object Calls are made to the proxy The proxy then forwards those calls to the base object 9

10 Book definition: The intent of the Proxy pattern is to control access to an object by providing a surrogate, or placeholder, for it. 10

11 A Classic Example: Image Proxies A proxy is a substitute or stand-in for a base object As such, it is desirable for it to have an interface that is nearly identical to the interface of the base object The proxy works by receiving the calls and “judiciously” or selectively forwarding the requests to the underlying object 11

12 A classic use of proxies is to avoid the waiting time associated with loading images in applications Suppose the application contains graphical elements which hold the images A proxy for a graphical element could take the step of displaying a small, temporary image, while the real image is being loaded in the background 12

13 In other words, a load() call is issued to the proxy The proxy loads a temporary image and calls load() on the base object in the background The real load() may be set to run in a separate thread The user sees the temporary image quickly and can proceed using the application The loading time of the real image doesn’t affect response time 13

14 The book admits up front that the following shortcomings may apply to a proxy design: The resulting design may be brittle or fragile By this the authors mean that maintenance and modification may be difficult This is a bad sign for the application of a design pattern 14

15 The difficulty arises directly from the fact that the proxy is supposed to duplicate the interface of the underlying object If that interface includes lots of methods, you have two choices, which you’ve seen before Implement them all: This requires lots of work Implement only some of them: This means that the proxy can only handle a subset of calls that the base object can handle 15

16 The next overhead illustrates the idea of a graphical placeholder Initially an application would present the “Absent” icon After pressing the “Load” button, the “Loading…” icon would be displayed as a stand-in In the background, the loading of the real image would be started 16

17 17

18 From the standpoint of mechanics, the book proposes displaying.jpeg images as icons that are inserted into labels This is the basic syntax: ImageIcon icon = new ImageIcon(“images/fest.jpg”); JLabel label = new JLabel(icon); 18

19 The idea now is to give the JLabel a proxy instead of the real icon Then – The application makes use of the label – The label calls the proxy – And the proxy calls the base image/icon object The following sequence diagram illustrates the idea 19

20 20

21 Aside from problems that the book admits to with the example, there is another complication In the previous descriptions, reference was made to “loading an image in the background” The question is, what does this mean? 21

22 In this example it will mean having the proxy implement the Runnable interface so that the proxy can load the image in a separate thread If you’ve had CS 320 before or have encountered threads in some other setting, this might be meaningful If not, don’t worry Although central to this example, it is not central to the structure and intent of the design pattern 22

23 The overall plan of action for the proxy example is this: There is a Java class, ImageIcon, which is the graphical item which is displayed in a JLabel The proxy, ImageIconProxy is a subclass of the ImageIcon class 23

24 The ImageIconProxy class has three instance variables for images A static ImageIcon variable for the Absent icon A static ImageIcon variable for the Loading icon And a non-static ImageIcon variable for whichever ImageIcon is currently displayed 24

25 The ImageIconProxy class has an instance variable to hold the String path name of the real image to load The ImageIconProxy class also has an instance variable that holds a reference to the frame of the application that is using it 25

26 The ImageIconProxy class overrides a few of the many methods in the ImageIcon class In particular it has a load() method that triggers the loading of an image Because it implements Runnable, it also has a run() method See the UML diagram on the following overhead 26

27 27

28 When an instance of the ImageIconProxy class is constructed, it takes in the String path name of an actual image to be loaded The load() method takes in a reference to a frame as a parameter When called, the load() method switches the current image to “Loading” It then repaints the frame After that, it starts a new thread for loading the actual image 28

29 The run() method basically just does the loading of the actual image The code for the ImageIconProxy follows There are a few blanks in the code for the challenge that comes afterwards 29

30 import java.awt.*; import javax.swing.*; public class ImageIconProxy extends ImageIcon implements Runnable { static final ImageIcon ABSENT = new ImageIcon(ClassLoader.getSystemResource("images/absent.jpg")); static final ImageIcon LOADING = new ImageIcon(ClassLoader.getSystemResource("images/loading.jpg")); ImageIcon current = ABSENT; protected String filename; protected JFrame callbackFrame; 30

31 public ImageIconProxy(String filename) { super(ABSENT.getImage()); this.filename = filename; } public void load(JFrame callbackFrame) { this.callbackFrame = callbackFrame; current = LOADING; callbackFrame.repaint(); new Thread(this).start(); } public void run() { current = new ImageIcon(ClassLoader.getSystemResource(filename)); callbackFrame.pack(); } 31

32 public int getIconHeight() { // Challenge! } public int getIconWidth() { // Challenge! } public synchronized void paintIcon(Component c, Graphics g, int x, int y) { // Challenge! } 32

33 Challenge 11.1 An ImageIconProxy object accepts three image display calls that it must pass on to the current image. Write the code for getIconHeight(), getIconWidth(), and paintIcon() for the ImageIconProxy class. 33

34 Solution 11.1 One solutions is: [See next overhead.] 34

35 public int getIconHeight() { return current.getIconHeight(); } public int getIconWidth() { return current.getIconWidth(); } public synchronized void paintIcon(Component c, Graphics g, int x, int y) { current.paintIcon(c, g, x, y); } 35

36 Before moving on with the book’s discussion, I would simply like to illustrate exactly how their example of a proxy works structurally The ImageIconProxy class has an instance variable which is a reference to an ImageIcon, the current image The situation can be diagrammed as shown on the following overhead 36

37 37

38 Recall that the ImageIconProxy class is a subclass of the ImageIcon class It also implements the Runnable interface Combining the previous diagram with the diagram that the book gave of the inheritance and interface relationships gives the diagram on the following overhead I don’t claim that this is a generic picture of the structure of a proxy It is, however, a more complete picture of what the book has done to create this proxy class 38

39 39

40 Challenge 11.2 The ImageIconProxy class is not a well- designed, reusable component. Point out two problems with the design. 40

41 Solution 11.2 Problems with the design include the following: 1. Forwarding only a subset of calls to an underlying ImageIcon object is dangerous. The ImageIconProxy class inherits a dozen fields and at least 25 methods from the ImageIcon class. 41

42 To be a true proxy, the ImageIconProxy object needs to forward most or all of these calls. Thorough forwarding would require many potentially erroneous methods, and this code would require maintenance as the ImageIcon class and its superclasses change over time. [Note that when the authors say erroneous, what the apparently mean is that trying to completely duplicate the interface would be error prone.] 42

43 2. You might question whether the “Absent” image and the desired image are in the right places in the design. It might make more sense to have the images passed in rather than making the class responsible for finding them. [This seems like a relatively minor criticism. In their second, improved design the authors don’t really change this.] 43

44 In summary, the software design presented so far does include the Proxy design pattern However, the design that results from using this pattern is apparently NOT so good Whenever you apply a pattern, it’s not sufficient to justify its use on the grounds that it’s a pattern 44

45 Its use has to lead to a better design That said, even though this design may be poor, it may also be the clearest illustration of the use of the Proxy design pattern that is presented in this chapter 45

46 Image Proxies Reconsidered Preliminary comment mode on: What the authors do next is quite simple I’m not sure their explanation really makes it clear what’s happening because it’s so simple To give a preview, what they do is stop trying to make a proxy Instead, they solve their design problem with a subclass with no pretenses to being a proxy 46

47 The key point is this: With a proxy, you are either committed to reproducing the whole interface Or you decide to do a subset With the subclass solution you rely on all of the inherited methods of the superclass Plus you add a few selected methods needed for the application 47

48 The book now replaces the ImageIconProxy class with a LoadingImageIcon class which is a subclass of ImageIcon The LoadingImageIcon class has two methods in it, load() and run() The ImageIconProxy class had a few more methods in it, in particular paintIcon() 48

49 The key idea is that fundamentally the ImageIcon class contains an instance of the Image class The ImageIcon class contains all the methods needed for manipulating the image It is much cleaner to simply let the LoadingImageIcon class inherit and use these methods rather than trying to duplicate them A UML diagram of the new solution is given on the following overhead 49

50 50

51 The code for the LoadImageIcon class follows The basic idea behind load() and run() is similar to before However, the code is simpler because it relies more directly on the ImageIcon class There are a few blanks in the code for the challenge that comes afterwards 51

52 import javax.swing.ImageIcon; import javax.swing.JFrame; public class LoadingImageIcon extends ImageIcon implements Runnable { static final ImageIcon ABSENT = new ImageIcon(ClassLoader.getSystemResource("images/absent.jpg")); static final ImageIcon LOADING = new ImageIcon(ClassLoader.getSystemResource("images/loading.jpg")); protected String filename; protected JFrame callbackFrame; 52

53 public LoadingImageIcon(String filename) { super(ABSENT.getImage()); this.filename = filename; } public void load(JFrame callbackFrame) { // Challenge! } public void run() { // Challenge! } 53

54 Challenge 11.3 Fill in the code for load() and run() in LoadingImageIcon. 54

55 Solution 11.3 The load() method sets the image to Loading…, whereas the run() method, executing in a separate thread, loads the desired image: [See next overhead.] 55

56 public void load(JFrame callbackFrame) { this.callbackFrame = callbackFrame; setImage(LOADING.getImage()); callbackFrame.repaint(); new Thread(this).start(); } public void run() { setImage(new ImageIcon(ClassLoader.getSystemResource(filename)).getImage()); callbackFrame.pack(); } 56

57 Remote Proxies As stated at the beginning of this set of overheads, code running on remote machines is beyond the scope of this course However, it is worth noting how the idea of a proxy might be useful The proxy runs on the local machine and local code calls it The proxy does what it can to satisfy the request locally while forwarding calls to the remote object 57

58 This model is useful because remote calls can be time-consuming and they use resources (network, computing) beyond the local machine That is the extent to which this topic will be covered in this course Figures 11.5, 11.6, and B.14 have been tipped in below for future reference, but they can be ignored The next topic to be covered will be dynamic proxies 58

59 59

60 60

61 61

62 Dynamic Proxies The full treatment of dynamic proxies, like remote proxies, is beyond the scope of this course As presented in the book, dynamic proxies rely on Java reflection, which is a large and relatively complicated topic 62

63 You encountered the tip of the iceberg in CS 202 when you saw methods that were coded using calls like getClass() rather than hardcoding a class or using the instanceof operator to establish what class an object was an instance of One way of limiting the number of methods a proxy has to implement is to have the proxy only apply to a given interface that a class implements 63

64 This is significant in the reflection context because, just as there is a method that returns the class an object belongs to, there are methods that will return the interfaces a class implements In other words, it’s possible to dynamically find out what methods a class implements as a result of implementing a given interface 64

65 Although it is not useful to consider the full complexity of dynamic proxies, the intent of these proxies as explained by the authors is worth considering The scenario is this: Suppose you want to instrument code This means that you would like to insert debugging or testing statements, for example, into the code 65

66 Rather than inserting those statements directly into a base class, you can write a proxy class The methods of the proxy class would wrap calls to the corresponding methods in the base class Keep in mind that you are not necessarily committed to doing this for all methods In general, you will probably be doing testing on a class for some role it plays based on an interface it implements Then it’s only necessary to have modified versions of the methods belonging to the interface 66

67 Both before and after the wrapped calls, any other code or calls could be inserted The debugging or testing can be conducted on the proxy rather than messing up the base class When doing this without the reflection machinery, it would involve a considerable amount of code duplication If you master reflection, the process of creating and calling dynamic proxies can be largely automated 67

68 Summary A proxy is a placeholder object that manages access to a target object A proxy can insulate clients from various aspects of target object code, like the time taken to load a graphics object A proxy can also wrap calls to the target’s methods, allowing the insertion of other code before and after 68

69 The Proxy design pattern is responsibility based A proxy assumes responsibility for the target when the client makes a call The very nature of the proxy leads to its weakness as a design pattern The proxy is tightly coupled with the target 69

70 A choice has to be made between trying to implement the whole interface of the target and implementing only part Implementing it all is a lot of work Implementing part potentially means “gaps” in what can be done with the proxy Either way, the proxy is heavily dependent on the target class and any changes made to it 70

71 The End 71


Download ppt "Unit 6 Proxy Summary prepared by Kirk Scott 1. Design Patterns in Java Chapter 11 Proxy Summary prepared by Kirk Scott 2."

Similar presentations


Ads by Google