设计模式之代理模式

终于……看到了……代理模式……

我觉得……

这个模式……

真的……

好难啊……

首先是远程代理

↑都是这个东西好难

使用代理模式创建代表(representative)对象,让代表对象控制某对象的访问,被代理的对象可以是远程的对象,创建开销大的对象或者需要安全控制的对象

类图:

RealSubject是真正做事的对象,它是被Proxy代理和控制访问的对象。客户与RealSubject的交互都必须通过Proxy。

远程代理:

虚拟代理:

栗子:

写一个程序展示CD封面,当封面没有加载好的时候,就显示“加载中。。。”

创建一个代理类,当照片没有加载好的时候,就显示加载中,但加载好之后,就好所有方法委托给真正的照片类。

为什么要虚拟代理呢?因为没加载好的时候,还没有图片,这个代理就是一个虚拟的图片,,,

<span style="color: #0000ff;">import<span style="color: #000000;"> javax.swing.Icon;
<span style="color: #0000ff;">import
<span style="color: #000000;"> javax.swing.ImageIcon;

<span style="color: #008000;">//<span style="color: #008000;"> 代理Icon也要实现Icon接口
<span style="color: #0000ff;">public <span style="color: #0000ff;">class ImageProxy <span style="color: #0000ff;">implements<span style="color: #000000;"> Icon {
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
<span style="color: #0000ff;">boolean retrieving = <span style="color: #0000ff;">false<span style="color: #000000;">;

</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; URL是图片资源位置</span>
<span style="color: #0000ff;"&gt;public</span><span style="color: #000000;"&gt; ImageProxy(URL url) {
    imageURL </span>=<span style="color: #000000;"&gt; url;
}
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 在图像加载完毕前  返回默认的宽和高</span>
<span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; getIconWidth() {
    </span><span style="color: #0000ff;"&gt;if</span> (imageIcon != <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;) {
        </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; imageIcon.getIconWidth();
    } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; {
        </span><span style="color: #0000ff;"&gt;return</span> 800<span style="color: #000000;"&gt;;
    }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; getIconHeight() {
    </span><span style="color: #0000ff;"&gt;if</span> (imageIcon != <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;) {
        </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; imageIcon.getIconHeight();
    } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; {
        </span><span style="color: #0000ff;"&gt;return</span> 600<span style="color: #000000;"&gt;;
    }
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span> paintIcon(<span style="color: #0000ff;"&gt;final</span> Component c,Graphics g,<span style="color: #0000ff;"&gt;int</span> x,<span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; y) {

    </span><span style="color: #0000ff;"&gt;if</span> (imageIcon != <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;) {
        </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 如果已经有Icon  就告诉它画出自己</span>

<span style="color: #000000;"> imageIcon.paintIcon(c,g,x,y);
} <span style="color: #0000ff;">else<span style="color: #000000;"> {
<span style="color: #008000;">//<span style="color: #008000;"> 否则就显示加载中
g.drawString("Loading CD cover,please wait...",x+300,y+190<span style="color: #000000;">);
<span style="color: #0000ff;">if (!<span style="color: #000000;">retrieving) {
<span style="color: #008000;">//<span style="color: #008000;"> 如果我们还有试着取出图像 那么就开始取图像
retrieving = <span style="color: #0000ff;">true<span style="color: #000000;">;
retrievalThread = <span style="color: #0000ff;">new Thread(<span style="color: #0000ff;">new<span style="color: #000000;"> Runnable() {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> run() {
<span style="color: #0000ff;">try<span style="color: #000000;"> {
<span style="color: #008000;">//<span style="color: #008000;"> 要在这里加载真正的Icon图像
<span style="color: #008000;">//<span style="color: #008000;"> 请注意 加载图像和ImageIcon是同步的 也就是说 只有在加载完成之后 ImageIcon构造器才会返回
<span style="color: #008000;">//<span style="color: #008000;"> 这样 我们的程序就会耗在这里 动弹不得 也没办法显示消息
<span style="color: #008000;">//<span style="color: #008000;"> 我们不希望挂起整个用户界面 所以用另一个线程取出图像
<span style="color: #008000;">//<span style="color: #008000;"> 在线程中 我们实例化此Icon对象 其构造器会在图像加载完成后才返回
<span style="color: #008000;">//<span style="color: #008000;"> 当图像准备好时 我们告诉Swing要重绘
imageIcon = <span style="color: #0000ff;">new ImageIcon(imageURL,"CD cover"<span style="color: #000000;">);
c.repaint();
} <span style="color: #0000ff;">catch<span style="color: #000000;"> (Exception e) {
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}

}

然后是显示图片的ImageComponent类

java.awt.* javax.swing.*<span style="color: #0000ff;">class ImageComponent <span style="color: #0000ff;">extends<span style="color: #000000;"> JComponent {
<span style="color: #0000ff;">private<span style="color: #000000;"> Icon icon;

</span><span style="color: #0000ff;"&gt;public</span><span style="color: #000000;"&gt; ImageComponent(Icon icon) {  
    </span><span style="color: #0000ff;"&gt;this</span>.icon =<span style="color: #000000;"&gt; icon;
}  

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setIcon(Icon icon) {  
    </span><span style="color: #0000ff;"&gt;this</span>.icon =<span style="color: #000000;"&gt; icon;
}  

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; paintComponent(Graphics g) {  
    </span><span style="color: #0000ff;"&gt;super</span><span style="color: #000000;"&gt;.paintComponent(g);  
    </span><span style="color: #0000ff;"&gt;int</span> w =<span style="color: #000000;"&gt; icon.getIconWidth();  
    </span><span style="color: #0000ff;"&gt;int</span> h =<span style="color: #000000;"&gt; icon.getIconHeight();  
    </span><span style="color: #0000ff;"&gt;int</span> x = (800 - w)/2<span style="color: #000000;"&gt;;  
    </span><span style="color: #0000ff;"&gt;int</span> y = (600 - h)/2<span style="color: #000000;"&gt;;  
    icon.paintIcon(</span><span style="color: #0000ff;"&gt;this</span><span style="color: #000000;"&gt;,y);  
}  

}

测试类:

java.net.* java.awt.event.* javax.swing.* java.util.*<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> ImageProxyTestDrive {

ImageComponent imageComponent;  
JFrame frame </span>= <span style="color: #0000ff;"&gt;new</span> JFrame("CD封面加载器"<span style="color: #000000;"&gt;);
JMenuBar menuBar;  </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 菜单栏  </span>
JMenu menu;        <span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 菜单  </span>
Map<String,String> cds = <span style="color: #0000ff;"&gt;new</span> HashMap<><span style="color: #000000;"&gt;();

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;static</span> <span style="color: #0000ff;"&gt;void</span> main (String[] args) <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; Exception {  
    </span><span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; ImageProxyTestDrive();
}  

</span><span style="color: #0000ff;"&gt;public</span> ImageProxyTestDrive() <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; Exception{  

    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 构造菜单项用的, key=CD名,value=URL  </span>
    cds.put("轨迹","http://images.cnblogs.com/cnblogs_com/wenruo/873448/o_%E8%BD%A8%E8%BF%B9.png"<span style="color: #000000;"&gt;);  
    cds.put(</span>"分我一半的眼泪","http://images.cnblogs.com/cnblogs_com/wenruo/873448/o_%E5%88%86%E6%88%91%E4%B8%80%E5%8D%8A%E7%9A%84%E7%9C%BC%E6%B3%AA.jpg"<span style="color: #000000;"&gt;);  
    cds.put(</span>"光荣","http://images.cnblogs.com/cnblogs_com/wenruo/873448/o_%E5%85%89%E8%8D%A3.png"<span style="color: #000000;"&gt;);  
    cds.put(</span>"画中仙","http://images.cnblogs.com/cnblogs_com/wenruo/873448/o_%E7%94%BB%E4%B8%AD%E4%BB%99.jpg"<span style="color: #000000;"&gt;);  

    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 设置初始的CD封面  </span>
    URL initialURL = <span style="color: #0000ff;"&gt;new</span> URL(cds.get("轨迹"<span style="color: #000000;"&gt;));
    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; 建立菜单栏  </span>
    menuBar = <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; JMenuBar();
    menu </span>= <span style="color: #0000ff;"&gt;new</span> JMenu("Favorite CDs"<span style="color: #000000;"&gt;);
    menuBar.add(menu);
    frame.setJMenuBar(menuBar);

    </span><span style="color: #0000ff;"&gt;for</span>(Entry<String,String><span style="color: #000000;"&gt; e : cds.entrySet()) {  
        String name </span>=<span style="color: #000000;"&gt; e.getKey();
        String url </span>=<span style="color: #000000;"&gt; e.getValue();
        JMenuItem menuItem </span>= <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; JMenuItem(name);
        menu.add(menuItem);   
        menuItem.addActionListener(</span><span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; ActionListener() {
              </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; actionPerformed(ActionEvent event) {
                </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
                    imageComponent.setIcon(</span><span style="color: #0000ff;"&gt;new</span> ImageProxy(<span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; URL(url)));
                } </span><span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (MalformedURLException e) {
                    e.printStackTrace();
                }
                frame.repaint();
              }  
        });  
    }  

    </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; set up frame and menus  </span>
    Icon icon = <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; ImageProxy(initialURL);
    imageComponent </span>= <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; ImageComponent(icon);
    frame.getContentPane().add(imageComponent);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(</span>800,600<span style="color: #000000;"&gt;);
    frame.setVisible(</span><span style="color: #0000ff;"&gt;true</span><span style="color: #000000;"&gt;);
}

}

一个虚拟代理就完成了。。。

加载前:

在上面的例子中,每一次都是创建新的ImageProxy来取得对象,即使图像已经被取出来过,可以把已加载的图片放入缓存中,这就是缓存代理。

缓存代理(Caching Proxy)会维护之前创建的对象,当收到请求时,在可能的情况下返回缓存对象。

  

动态代理:Java在java.lang.reflect包中有自己的代理支持,利用这个包你可以在运行时动态地创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是在运行时被创建的,我们称这个技术为:动态代理。

动态代理类图:

动态代理的实现

有一个系统,存有每个人的信息,和每个人的评分。现在希望每个人不能给自己评分,而更改个人信息只有自己能做到。

于是设计两个代理,一个控制访问自己的类,一个控制访问其他人。

首先是个人信息的接口:

</span><span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setName(String name); </span><span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setGender(String gender); </span><span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setInterests(String interests); </span><span style="color: #0000ff;"&gt;void</span> setHotOrNotRating(<span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; rating);

}

具体实现类

PersonBeanImpl ratingCount = 0.name =.gender =.interests =</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; getHotOrNotRating() { </span><span style="color: #0000ff;"&gt;if</span> (ratingCount == 0) <span style="color: #0000ff;"&gt;return</span> 0<span style="color: #000000;"&gt;; </span><span style="color: #0000ff;"&gt;return</span> (rating /<span style="color: #000000;"&gt; ratingCount); } </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setName(String name) { </span><span style="color: #0000ff;"&gt;this</span>.name =<span style="color: #000000;"&gt; name; } </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setGender(String gender) { </span><span style="color: #0000ff;"&gt;this</span>.gender =<span style="color: #000000;"&gt; gender; } </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; setInterests(String interests) { </span><span style="color: #0000ff;"&gt;this</span>.interests =<span style="color: #000000;"&gt; interests; } </span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span> setHotOrNotRating(<span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; rating) { </span><span style="color: #0000ff;"&gt;this</span>.rating +=<span style="color: #000000;"&gt; rating; ratingCount</span>++<span style="color: #000000;"&gt;; }

}

创建两个InvocationHandler,一个给拥有者使用

<span style="color: #0000ff;">public <span style="color: #0000ff;">class OwnerInvocationHandler <span style="color: #0000ff;">implements<span style="color: #000000;"> InvocationHandler {
PersonBean person;

</span><span style="color: #0000ff;"&gt;public</span><span style="color: #000000;"&gt; OwnerInvocationHandler(PersonBean person) {
    </span><span style="color: #0000ff;"&gt;this</span>.person =<span style="color: #000000;"&gt; person;
}

@Override
</span><span style="color: #0000ff;"&gt;public</span> Object invoke(Object proxy,Method method,Object[] args) <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; Throwable {

    </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
        </span><span style="color: #0000ff;"&gt;if</span> (method.getName().startsWith("get"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; method.invoke(person,args);
        } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (method.getName().equals("setHotOrNotRating"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;throw</span> <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; IllegalAccessException();
        } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (method.getName().startsWith("set"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; method.invoke(person,args);
        }
    } </span><span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (InvocationTargetException e) {
        e.printStackTrace();
    }

    </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;;
}

}

一个给非拥有者使用

<span style="color: #0000ff;">public <span style="color: #0000ff;">class NotOwnerInvocationHandler <span style="color: #0000ff;">implements<span style="color: #000000;"> InvocationHandler {
PersonBean person;

</span><span style="color: #0000ff;"&gt;public</span><span style="color: #000000;"&gt; NotOwnerInvocationHandler(PersonBean person) {
    </span><span style="color: #0000ff;"&gt;this</span>.person =<span style="color: #000000;"&gt; person;
}

@Override
</span><span style="color: #0000ff;"&gt;public</span> Object invoke(Object proxy,Object[] args) <span style="color: #0000ff;"&gt;throws</span><span style="color: #000000;"&gt; IllegalAccessException {

    </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
        </span><span style="color: #0000ff;"&gt;if</span> (method.getName().startsWith("get"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; method.invoke(person,args);
        } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (method.getName().equals("setHotOrNotRating"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; method.invoke(person,args);
        } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (method.getName().startsWith("set"<span style="color: #000000;"&gt;)) {
            </span><span style="color: #0000ff;"&gt;throw</span> <span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; IllegalAccessException();
        }
    } </span><span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (InvocationTargetException e) {
        e.printStackTrace();
    }

    </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;;
}

}

测试类:

<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> MatchMakingTestDrive {
<span style="color: #0000ff;">public <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> main(String[] args) {
MatchMakingTestDrive test = <span style="color: #0000ff;">new<span style="color: #000000;"> MatchMakingTestDrive();
test.drive();
}

</span><span style="color: #0000ff;"&gt;public</span><span style="color: #000000;"&gt; MatchMakingTestDrive() {
    initializeDatabsae();
}

</span><span style="color: #0000ff;"&gt;public</span> <span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; drive() {
    PersonBean joe </span>= getPersonFromDatabase("Joe JavaBean"<span style="color: #000000;"&gt;);
    PersonBean ownerProxy </span>=<span style="color: #000000;"&gt; getOwnerProxy(joe);
    System.out.println(</span>"Name is " +<span style="color: #000000;"&gt; ownerProxy.getName());
    ownerProxy.setInterests(</span>"bowling,Go"<span style="color: #000000;"&gt;);
    System.out.println(</span>"Interests set from owner proxy"<span style="color: #000000;"&gt;);
    </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
        ownerProxy.setHotOrNotRating(</span>10);<span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;不能给自己平分</span>
    } <span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (Exception e) {
        System.out.println(</span>"Can't set rating from owner proxy"<span style="color: #000000;"&gt;);
    }

    System.out.println(</span>"Rating is " +<span style="color: #000000;"&gt; ownerProxy.getHotOrNotRating());

    PersonBean nonOwnerProxy </span>=<span style="color: #000000;"&gt; getNonOwnerProxy(joe);
    System.out.println(</span>"Name is " +<span style="color: #000000;"&gt; nonOwnerProxy.getName());
    </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt; {
        nonOwnerProxy.setInterests(</span>"bowling,Go"<span style="color: #000000;"&gt;);
    } </span><span style="color: #0000ff;"&gt;catch</span><span style="color: #000000;"&gt; (Exception e) {
        System.out.println(</span>"Can't set interests from non owner proxy"<span style="color: #000000;"&gt;);
    }
    nonOwnerProxy.setHotOrNotRating(</span>3<span style="color: #000000;"&gt;);
    System.out.println(</span>"Rating set from non owner proxy"<span style="color: #000000;"&gt;);
    System.out.println(</span>"Rating is " +<span style="color: #000000;"&gt; nonOwnerProxy.getHotOrNotRating());
}

PersonBean getOwnerProxy(PersonBean person) {
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; (PersonBean) Proxy.newProxyInstance(
                            person.getClass().getClassLoader(),person.getClass().getInterfaces(),</span><span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; OwnerInvocationHandler(person));
}

PersonBean getNonOwnerProxy(PersonBean person) {
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; (PersonBean) Proxy.newProxyInstance(
                            person.getClass().getClassLoader(),</span><span style="color: #0000ff;"&gt;new</span><span style="color: #000000;"&gt; NotOwnerInvocationHandler(person));
}

</span><span style="color: #008000;"&gt;/**</span><span style="color: #008000;"&gt;**********假装这是数据库实现*************</span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;

ArrayList</span><PersonBean><span style="color: #000000;"&gt; beans;

</span><span style="color: #0000ff;"&gt;void</span><span style="color: #000000;"&gt; initializeDatabsae() {
    beans </span>= <span style="color: #0000ff;"&gt;new</span> ArrayList<><span style="color: #000000;"&gt;();
    beans.add(</span><span style="color: #0000ff;"&gt;new</span> PersonBeanImpl("Joe JavaBean","男","学习"<span style="color: #000000;"&gt;));
}

PersonBean getPersonFromDatabase(String name) {
    </span><span style="color: #0000ff;"&gt;for</span> (<span style="color: #0000ff;"&gt;int</span> i = 0; i < beans.size(); ++<span style="color: #000000;"&gt;i) {
        PersonBean person </span>=<span style="color: #000000;"&gt; beans.get(i);
        </span><span style="color: #0000ff;"&gt;if</span> (person.getName().equals(name)) <span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; person;
    }
    </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #0000ff;"&gt;null</span><span style="color: #000000;"&gt;;
}

}

一些其他的代理模式:

防火墙代理:控制网络资源的访问,保护主题免于“坏客户”的侵害。

智能引用代理:当主题被引用时,进行额外的动作,例如计算一个对象呗引用的次数。

缓存代理:为开销大的运算结果提供暂时的存储,它也允许多个客户共享结果,以减少计算或网络延迟。

同步代理:在多线程的情况下为主题提供安全的访问。

复杂隐藏代理:用来隐藏一个类的复杂集合的复杂度,并进行访问控制。

写入时复制代理:用来控制对象的复制,方法是延迟对象的复制,直到客户真的需要为止。这是虚拟代理的变体。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结