Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 11 Proxy Summary prepared by Kirk Scott 1.

Similar presentations


Presentation on theme: "Chapter 11 Proxy Summary prepared by Kirk Scott 1."— Presentation transcript:

1 Chapter 11 Proxy Summary prepared by Kirk Scott 1

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

3 The Downy Woodpecker (Picoides pubescens) is a species of woodpecker, the smallest in North America.specieswoodpecker North America 3

4 4

5 5

6 The Introduction Before the Introduction The chapter in the book is broken into four different parts 1. An illustration of the design pattern for image loading – This example shows the accepted use of classes and relationships between them for implementing the proxy pattern 2. A refactoring of the original design – The idea is that the same functional goal is achieved but by means which might be better 6

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

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

9 Beginning of Book Material Responsibility in a design means that every class implements the code to support itself Recall how the builder pattern relaxed this Some of the construction logic was offloaded Proxy is another design pattern where, in order to achieve a particular goal, responsibility for a given class is apportioned into another class 9

10 In simple terms, a proxy is a substitute that you give to a client when it requests a base object There are 3 cases where this might be desirable: 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 10

11 In those cases a software design might include a proxy class A proxy object stands in for a base object Calls are made on the proxy object The proxy then forwards those calls to the base object In other words, the proxy is responsible for providing a public interface for/receiving calls that are ultimately aimed at another, base class 11

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

13 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 a generic interface (set of public methods) that is nearly identical to the interface of the base object The proxy works by receiving the calls and “judiciously”, selectively, or “with modifications” forwarding the requests to the underlying object 13

14 The term “stand-in” has been used to describe a proxy A proxy might also be understood as a wrapper, depending on how it’s implemented Or it might be understood as a go-between Because it stands between the client and the base object, it might forward some calls unchanged, while other calls may have code added or modified in some other way 14

15 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 15

16 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 16

17 The user sees the temporary image quickly and can proceed using the application The loading time of the real image doesn’t affect the immediate response time needed to show the temporary image 17

18 Something else to consider: If the real image is important, can you really proceed to use the application without it? If it’s not important, does it really matter what image you’re seeing on the screen? Consider splash screens in Web pages Basically, you’d like to show users one thing In the meantime, showing them something else is better than showing them nothing at all 18

19 An Illustration of How the Pattern Might Be Used The next overhead illustrates the idea of a graphical placeholder in an application that is supposed to display a picture 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, and eventually the real image would be displayed 19

20 20

21 The Mechanics of the Example From the standpoint of mechanics, the book proposes displaying.jpg 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); 21

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

23 23

24 Threads in the Example In the previous descriptions, reference was made to “loading an image in the background” In this example this will mean having the proxy implement the Runnable interface so that the proxy can load the image in a separate thread 24

25 If you haven’t had CS 320 before or threads in some other setting, don’t worry Although part of this example, it is not central to the structure and intent of the design pattern 25

26 If you have encountered threads before, you might consider this thought: Multi-threading in a single processor environment may not lead to any real time savings The user will see the temporary icon immediately, but it still won’t be possible to do anything until the thread loading the real image finishes running In other words, this would be purely cosmetic (which might be desirable in its own right) 26

27 A UML Diagram for the Example A UML diagram showing the relationship between the ImageIcon and ImageIconProxy classes is given on the following overhead This will be followed by a discussion of the structure of the pattern in general Following that, the example will be covered in detail, with code 27

28 Example UML 28

29 Static Structure of the Pattern Example This is the structure of the proxy example: 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 The proxy class has an instance variable which is typed ImageIcon, the type of its superclass 29

30 The bare structure of the example can be summarized as shown in the simplified UML diagram on the following overhead 30

31 31

32 The intent is to create a proxy The structure used to do so is a class with a reference to an instance of its superclass This may seem a little weird, but it’s certainly possible We’re going to see the same structure in other patterns later on 32

33 Even though the book is interested in intent, it clearly identifies this pattern by structure As we will see, it ultimately finds the structure troublesome It will eventually abandon this structure in favor of a simpler structure which it will call a “proxy in spirit” 33

34 Continuing the Discussion of the Example The ImageIcon instance variable in the ImageIconProxy class is a reference to the icon which the proxy is currently displaying Initially it is a reference to the temporary image Later, it will refer to the real image icon when that one is finally being displayed 34

35 The ImageIconProxy class implements Runnable, so it has a run() method As mentioned already, that is part of the example, and it will continue to be shown It is incidental, not fundamental to the pattern 35

36 The ImageIconProxy class has two other instance variables for images A static ImageIcon variable for the Absent icon A static ImageIcon variable for the Loading icon Note that in reality these are constants, not variables 36

37 The ImageIconProxy class also has an instance variable to hold the String path name of the real image to load And the ImageIconProxy class has an instance variable that holds a reference to the frame of the application that is using it The frame reference is used to refresh what is shown on the screen when the ImageIconProxy variable takes on a new value 37

38 The ImageIconProxy class inherits the public interface of its superclass, ImageIcon The ImageIconProxy class overrides a few of the many methods in the ImageIcon class It also has a load() method that triggers the loading of an image 38

39 How It Works 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 the containing frame as a parameter When called, the load() method switches the current image to “Loading” It then repaints the frame 39

40 After that, the load() method starts a new thread for loading the actual image The run() method of the thread does the loading of the actual image In the book, the code for the ImageIconProxy class is given in partial form, followed by a challenge to complete it Instead of doing a challenge, the complete code is shown beginning on the following overhead. 40

41 ImageIconProxy Code 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; 41

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

43 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); } 43

44 The Structure of a Proxy in Its Most Basic Form The basic structure of the proxy pattern, as presented in the book, was mentioned earlier It is repeated again here in some depth for reference purposes The book is ready to critique the pattern and suggest an alternative It’s helpful to see exactly what it’s talking about 44

45 At the most basic level, 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 45

46 46

47 The ImageIconProxy class is a subclass of the ImageIcon class It also implements the Runnable interface A more complete diagram, including those elements, is shown on the following overhead Note that implementing the Runnable interface is incidental, but not necessarily fundamental to the pattern 47

48 48

49 In summary, the structure of the pattern can be described in this way: A subclass has an instance variable that is a reference to the subclass’s superclass Or, the subclass wraps an instance of its superclass The functional result is that the subclass provides an extended interface for working with an instance of the superclass 49

50 In the future we will see another design pattern, Decorator, where a subclass has a reference to an instance of its superclass Decorator is definitely useful, so that structure is not necessarily bad However, we will see now that the book is backing away from its use in Proxy because it may be less than ideal 50

51 Problems with the Example Application of the Pattern Challenge 11.2 The ImageIconProxy class is not a well- designed, reusable component. Point out two problems with the design. 51

52 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. To be a true proxy, the ImageIconProxy object needs to forward most or all of these calls. 52

53 Thorough forwarding would require many potentially erroneous methods, and this code would require maintenance as the ImageIcon class and its superclasses change over time.” 53

54 Comment mode on: Note that when the authors say “erroneous”, it is not entirely clear what they mean. They may mean that due to the nature of the subclass, the inherited versions of the methods will not typically apply That would mean having to override most or all of the methods of the superclass 54

55 Or by “erroneous” they may mean that trying to completely duplicate the interface would be error prone Their statement does make it clear that maintenance would be a problem if the methods of the superclass that are overridden are subject to change 55

56 They may also be suggesting that you might try to ease your work by not overriding all methods, relying on inheritance for “unimportant” methods, even if the inherited version doesn’t apply to the subclass Or they may be suggesting that you might supply a number of bogus overridden implementations in the subclass 56

57 [Back to the problems identified by the book.] “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.] 57

58 Shortcomings of the Pattern 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 58

59 The difficulty arises directly from the fact that the proxy is supposed to duplicate the public interface of the underlying object If that interface includes lots of methods, you have two choices 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 59

60 In the future we will see another design pattern, Bridge, where this question comes up Bridge is definitely useful, and we will see that you simply have to make a choice on whether to implement some or all of the methods In theory you could do the same with Proxy, but again, the book is edging towards a different solution 60

61 Applying a Pattern May Not Always Be a Good Idea In summary, the software design presented so far does include the Proxy design pattern However, the authors aren’t satisfied that the design that results from using this pattern is good Whenever you apply a pattern, it’s not sufficient to justify its use on the grounds that it’s a pattern 61

62 Its use has to lead to a better design As a matter of fact, the authors’ critique seems to be of the structure of the pattern itself, not just its application Whether good or not, the foregoing example is the clearest illustration of the structure of the Proxy design pattern that is presented by the book 62

63 Image Proxies Reconsidered What the authors do next is quite simple It is so simple that once you get involved in the book’s explanation you may not realize how simple it is What they do is stop trying to make a proxy by having a subclass with a reference to an instance of its superclass 63

64 They solve their design problem with a subclass with no pretenses to having the structure of a proxy as shown so far The subclass no longer contains a reference to a superclass object The subclass is simply “a kind of” its superclass It is not a wrapper for an instance of its superclass 64

65 With the proxy structure, this is the question that confronts you: How much of the public interface that you have inherited from the superclass will you need to modify when passing those calls on to the instance of the superclass that is wrapped in the subclass? Does the whole interface have to be reworked? Is it sufficient to implement a subset? 65

66 What you want to accomplish with your new design is the same as with a proxy, but the task is clearer You’re back to the familiar problem of designing a subclass with special, useful characteristics that distinguish it from the superclass 66

67 With the subclass solution you rely on all of the inherited methods of the superclass and override as needed Plus you may add selected methods as needed 67

68 Intent and “Proxy in Spirit” The book starts referring to its new design as a proxy in spirit If you accept the book’s idea that a pattern is defined by intent rather than structure, then a “proxy in spirit” is simply a proxy that has a different structure You should be familiar both the structure they have given and the intent However they’re coded, cases arise where “stand-ins” are needed for objects in applications 68

69 Specifics of the Book’s New Solution There is still an ImageIcon class It has an instance variable of type Image There is a LoadingImageIcon subclass of ImageIcon instead of an ImageIconProxy subclass The LoadingImageIcon subclass doesn’t contain a reference to an instance of ImageIcon Instead, it inherits the Image instance variable from ImageIcon 69

70 The ImageIcon class contains all the methods needed for manipulating the Image instance variable The LoadingImageIcon class inherits these methods The LoadingImageIcon class also has these two methods in it, load() and run() A UML diagram of the new solution is given on the following overhead 70

71 New Solution UML 71

72 Code for the New Solution 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 72

73 Just like with the code for the previous example, the book gives partial code for the LoadingImageIcon class followed by a challenge to complete it Instead of doing a challenge, the complete code is given here. 73

74 LoadingImageIcon Code 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; public LoadingImageIcon(String filename) { super(ABSENT.getImage()); this.filename = filename; } 74

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

76 Another Example The following example is given for one reason only: It is an attempt to illustrate what good an application of the proxy pattern might be. It emphatically doesn’t illustrate the structure of the pattern as given in the book In other words, you won’t find in it a subclass containing a reference to a superclass object 76

77 On the other hand, you can identify the class in this example which implements the desired functionality That is, like the book’s second example, you can identify that part of the application which is a “proxy in spirit” 77

78 The book’s discussion started with the question of displaying images. However, when I tried the book’s code, everything went so quickly when loading a local image that you didn’t see the “Loading…” icon For all practical purposes, it wasn’t apparent that any kind of proxy was in use 78

79 This example makes use of Web pages—local and remote ones—so that there can be a perceptible delay in showing them The pages are displayed in an editor screen The local ones display nicely A remote Web page will probably display strangely—but it will display, and display with a delay, which is the point 79

80 The set of screenshots on the following overheads shows what you see when using the application 80

81 81

82 82

83 83

84 84

85 A UML diagram for the application is given on the following overhead The JEditorPagePaneLoader class contains a load() method and a run() method It implements the proxy functionality The application could be improved, but when you run it you will find that it does serve the purpose of actually showing what happens on the screen 85

86 86

87 The code for the application is given on the following overheads for reference. It is unlikely that it will be read in class. 87

88 import javax.swing.JEditorPane; import java.io.IOException; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.lang.*; import java.util.*; public class EditorPane { public static void main(String[] args) { EditorPaneFrame myframe = new EditorPaneFrame(); myframe.setVisible(true); } 88

89 class EditorPaneFrame extends JFrame { private EditorPanePanel myEditorPanePanel; private final int FRAMEW = 1000; private final int FRAMEH = 500; 89

90 public EditorPaneFrame() { setTitle("EditorPane Frame"); setSize(FRAMEW, FRAMEH); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myEditorPanePanel = new EditorPanePanel(); Container contentPane = getContentPane(); contentPane.add(myEditorPanePanel, "Center"); JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu fileMenu = new JMenu("File"); menuBar.add(fileMenu); JMenuItem editorPaneItem = new JMenuItem("Load Editor Pane"); fileMenu.add(editorPaneItem); EditorPaneListener myEditorPaneListener = new EditorPaneListener(); editorPaneItem.addActionListener(myEditorPaneListener); } 90

91 private class EditorPaneListener implements ActionListener { public void actionPerformed(ActionEvent event) { String localString = ""; localString = JOptionPane.showInputDialog("Enter a URL"); myEditorPanePanel.setPage(localString); } 91

92 class EditorPanePanel extends JPanel { private JEditorPanePageLoader mypane; public EditorPanePanel() { try { mypane = new JEditorPanePageLoader(); this.add(mypane); } catch(IOException ioe) { System.out.println("Caught an I/O exception when trying to open URL."); System.out.println(ioe); } public void setPage(String stringURLIn) { mypane.loadPage(stringURLIn); } 92

93 class JEditorPanePageLoader extends JEditorPane implements Runnable { private String stringURL; public JEditorPanePageLoader() throws IOException { super("http://math.uaa.alaska.edu/~afkas/initiallocalpage.htm"); } public void loadPage(String stringURLIn) { stringURL = stringURLIn; try { setPage("http://math.uaa.alaska.edu/~afkas/loadingpage.htm"); } catch(IOException ioe) { System.out.println("Caught an I/O exception when trying to open URL."); System.out.println(ioe); } new Thread(this).start(); } 93

94 public void run() { try { setPage(stringURL); } catch(IOException ioe) { System.out.println("Caught an I/O exception when trying to open URL."); System.out.println(ioe); } 94

95 A UML Diagram for the Pattern from Lasater Lasater’s UML diagram is given on the next overhead. Using that author’s terminology, the RealSubject and the Proxy are both subclasses of a Subject class, and the Client has a reference to a subject In fact, under this plan, the client would have a superclass reference to a proxy object 95

96 The other part of the pattern is clearly shown: The proxy has an instance variable that is of the type RealSubject Because of the presence of the Subject superclass, the reference is to a sibling In the previous discussion, the so-called RealSubject was the superclass, so the reference was to a superclass 96

97 97

98 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 98

99 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 The basic idea is that you can instrument code by wrapping a base object with a proxy, where the proxy method code contains instrumentation which surrounds the forwarding of calls to the methods of the base object 99

100 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 it 100

101 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 101

102 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 102

103 The End 103


Download ppt "Chapter 11 Proxy Summary prepared by Kirk Scott 1."

Similar presentations


Ads by Google