《JAVA与模式》之门面模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述门面(Facade)模式的:

  门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。


 

医院的例子

  现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一 个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系 统的各个类打交道一样,不是一件容易的事情。

  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必须首先划价,然后缴费,才可以到化验部门做化验。化验后再回到门诊室。

  

  上图描述的是病人在医院里的体验,图中的方框代表医院。

  解决这种不便的方法便是引进门面模式,医院可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是门面模式的体现,病人只接触接待员,由接待员与各个部门打交道。

  

门面模式的结构

  门面模式没有一个一般化的类图描述,最好的描述方法实际上就是以一个例子说明。

  

  由于门面模式的结构图过于抽象,因此把它稍稍具体点。假设子系统内有三个模块,分别是ModuleA、ModuleB和ModuleC,它们分别有一个示例方法,那么此时示例的整体结构图如下:

  

  在这个对象图中,出现了两个角色:

  ●  门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

  ●  子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

源代码

  子系统角色中的类:

 public class ModuleA {
//示意方法
public void testA(){
System.out.println("调用ModuleA中的testA方法");
}
}
public class ModuleB {
//示意方法
public void testB(){
System.out.println("调用ModuleB中的testB方法");
}
}
public class ModuleC {
//示意方法
public void testC(){
System.out.println("调用ModuleC中的testC方法");
}
}

门面角色类:

public class Facade {
//示意方法,满足客户端需要的功能
public void test(){
ModuleA a = new ModuleA();
a.testA();
ModuleB b = new ModuleB();
b.testB();
ModuleC c = new ModuleC();
c.testC();
}
}

客户端角色类:

public class Client {

    public static void main(String[] args) {

        Facade facade = new Facade();
facade.test();
} }

Facade类其实相当于A、B、C模块的外观界面,有了这个Facade类,那么客户端就不需要亲自调用子系统中的A、B、C模块了,也不需要知 道系统内部的实现细节,甚至都不需要知道A、B、C模块的存在,客户端只需要跟Facade类交互就好了,从而更好地实现了客户端和子系统中A、B、C模 块的解耦,让客户端更容易地使用系统。


门面模式的实现

  使用门面模式还有一个附带的好处,就是能够有选择性地暴露方法。一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是子 系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。

  比如,定义如下A、B、C模块。

public class Module {
/**
* 提供给子系统外部使用的方法
*/
public void a1(){}; /**
* 子系统内部模块之间相互调用时使用的方法
*/
public void a2(){};
public void a3(){};
}
public class ModuleB {
/**
* 提供给子系统外部使用的方法
*/
public void b1(){}; /**
* 子系统内部模块之间相互调用时使用的方法
*/
public void b2(){};
public void b3(){};
}
public class ModuleC {
/**
* 提供给子系统外部使用的方法
*/
public void c1(){}; /**
* 子系统内部模块之间相互调用时使用的方法
*/
public void c2(){};
public void c3(){};
}
public class ModuleFacade {

    ModuleA a = new ModuleA();
ModuleB b = new ModuleB();
ModuleC c = new ModuleC();
/**
* 下面这些是A、B、C模块对子系统外部提供的方法
*/
public void a1(){
a.a1();
}
public void b1(){
b.b1();
}
public void c1(){
c.c1();
}
}

这样定义一个ModuleFacade类可以有效地屏蔽内部的细节,免得客户端去调用Module类时,发现一些不需要它知道的方法。比如a2() 和a3()方法就不需要让客户端知道,否则既暴露了内部的细节,又让客户端迷惑。对客户端来说,他可能还要去思考a2()、a3()方法用来干什么呢?其 实a2()和a3()方法是内部模块之间交互的,原本就不是对子系统外部的,所以干脆就不要让客户端知道。

一个系统可以有几个门面类

  在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只有一个门面类,而仅仅 是说对每一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统都有一个门面类,整个系统可以有数个门面类。

为子系统增加新行为

  初学者往往以为通过继承一个门面类便可在子系统中加入新的行为,这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。比如医院中的接待员并不是医护人员,接待员并不能为病人提供医疗服务。

门面模式的优点

  门面模式的优点:

  ●  松散耦合

  门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。

  ●  简单易用

  门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。

  ●  更好的划分访问层次

  通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。

      


门面模式在Tomcat中的使用

  Tomcat中门面模式使用的很多,因为Tomcat中有很多不同组件,每个组件要相互通信,但是又不能将自己内部数据过多的暴露给其他组件。用门面模式隔离数据是个很好的方法。

  下面是Request上使用的门面模式:

  

  使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类,并且重写doGet与doPost方法(当然只重写service方法也是可以的)。

public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { } }

  可以看出doGet与doPost方法有两个参数,参数类型是接口HttpServletRequest与接口 HttpServletResponse,那么从Tomcat中传递过来的真实类型到底是什么呢?通过debug会发现,在真正调用 TestServlet类之前,会经过很多Tomcat中的方法。如下图所示

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAo8AAAGRCAIAAACLxs5aAAAgAElEQVR4nO297e81SXnf2f9B/oA8WFllyUp+QQbuGaR+wctdZWXlDWvwYIaYldKJFFkbZaW1wMKEzARPLBO1kyiJCdmJNtggPElQgDY4i8kjGhszrB3LIunA2DE7ZoAZMBhjC8adF/10PVZXP51T59T3o6P7/p0+3VVXXVVd366rz+mr6AAAAACQNsW1DQAAAADAAlBrAAAAIHWg1gAAAEDq3Jtav/cvf//rXvPK9/7l77+2IYfTVEVZt9cq+4za27osqsbcfFpLwUmsGiBnjmUA7pX7Uesf/r4/88Pf92de95pXdt1Tr3vNK/u3zr5tXRYEQzKuSFMVkqq5iloPlpxV+3FqTfqTFDg5kpQWv+flaetytGAwyDGHOG4eLFcexJvUGqoNQDx3pdaffOq13XNv7l+ffOq1YbWeZ7emuv5kZ9BUzKjrqPVogbkHdaMjvSE2HGLSVFP3zUpPNH/+PH7Py9PWZVnS6xSvw9u6NMxt6/KqQ3jj2npuDAAgTLpq/clPfvLJJ5+M3LkPgHfPvfk97/7rr3vNK9/z7r/ePfdmPySudOIo4TgSqHUk1Lbxb1b29CZ+z0vTqxbz8mKnJKV0myPhYpgDABwSVetPfOIT3/u93/uKV7wicv/XveaV3Sdf233yta97zSu773ydvTXQkzLZshAsneaZpirKuhl2HqLFMn5Jo9pTYU1VlHWtdxZYaj0eRW2tmqaaC9J2LrfIs0OqNaudHF6WJSuHWBUK0jq7sc4xHWgVNNY7u4E3la+jl/e0nMFc1dblZBJZ5Fr+tzfyBujIsG0KlWgrFOBcQakhEOgjZ6gbI9YbQgtOYB8kdc0BQMKkqNa9VP/AD/xAvFr/11/69//uYx/tvvQLv/Kpjw9r60++dsXaet7S1pWeDOnESRdq/DYjnQbH4/kMNm8nO3tzlVZrfVQ/CfPrAGmn1yIuictqbddura25VW542dlt2YFeUY7iM7/E7yk8oR07bp0/dMdJUI9UgSFT1MWFkFqzT4yQgddH/lCXve8NIbcEZ7xhcQ1AFMmp9STVjz76aECtf+0X/sovvvfP/uJ7/+x7f/wv/JdPPdH//YH69d/+nWefe+q1zz312hX3rYct/lpUfe9LLYSsv+Vsa8ZjAyuLQCR8Osq4Ae8tYGSLaLXrIuFm7YGoOJ/0+erU2M30U6gcocWj8w0NXrUn72rbsf0H/J3YzfAtK5x6YVmtrfEydK68WJTXPfyawXH+8lA34wDkbYwT2FssrgGIIi21plIdVutf+If/4x/94Rdf/vZ//sn/409/6oPf1//90z/yP/36Z375uadeG/OdcKbWLFRKvgFjy4Y4xvnbEBulLoertX1zealFF1Jrw7KVar207jXWux2Tosg9g1XwDwoRMJa7+bH1qUaJsdCmxZkr0XHxGvouQV9X8FJpeahHqPWiE+RVCdbWACyTllo/+eSTryC8613v8vZsfup/ePkrH/vOb/+jv/1Xv+ff/8z/2v/9D/7PVzz/n3894vfWeklqTLjkxqSI4+nZ1PxbBfzsUOFxam3audwiqueeBavV2n7DcHYLRMJNV7G7CUY8nV+Kxe1peEIPgGF3fg/cHCezG+vgKjIuEk66U1+pEWuoS2srOG710eJQpxed5hBadAIfb961HACAk5Zax/Ov3v2nv/s7H/jO5x//8b/yPf/m//nz/d9/769F3ufmCxoVbh02V5W8FUtWPhFq3fGwoHd3+UC1Nu10WjSbVtb1trX1WPQkEzS4Wy3+EtjZjbXJdKBVkN5p3mptW9ozUIe6lCBiZ/g/rvyxtYtXJ3RYmM2ZNtLubqSb/T5aGOpkxHpDyHSCtzOW1gDEcatq/S//9ve8/NXmu7/9D5/4S3/yE//3/9L//VM/7IW+wRa2TqRYLh1BIJZwwH3eRPoIN60BiOVW1fqf/60/9fI3Pv3dr37kif/9T/y///h/7v+u/yrU+kga9Y3jOBJRghumiX2W2WaS6KOFe/oAAMKtqvW/+5kfev/b//j73/7Hf+qtf/4zH317//e/+LtvuLZdoEtECUAQ9BEAN8atqjUAAACQD1BrAAAAIHWg1gAAAEDq5KLW3335jz7xay/+/Z//rSee/jxeeOGF1/29/v7P/9Ynfu3F7778R9eebsEp5KLWH/mVL3/02a9+8aXvfOMPOrzwwguv+3t98aXvfPTZr37kV7587ekWnEIuav0TH/rCi996+cXf7776LbzwwguvO3y9+Pvdi996+Sc+9IVrT7fgFHJR6yee/vzv/kH3ld/DCy+88Lrb1+/+QffE05+/9nQLTiEjtf76t7sXvtm98M3uj/3gexdf/Z638GoeK6r37ynhX1TFI/Uz12/IzToQL3hYN/ZX6wdF+fivXtqAr38ban23ZKTWX/t296VvdF/6Rvf6n/yF17/7469/98e//yeH1+un17uHf/s9xetn31JI3tKYe0a8msfGMh57elsJUznVz24/vPvS01XxSP3M8p7t33xkfij1qhqfebIs3tL0JbDGfrZ+sN34yzuQeqCIc9qFX/DwhV4/+5biwZNtqLGfrR8U5d/87EE1Pl3RXnjmSZm4bTLma1Dr+yUjtX7p97vnv9E9/43u2S98efHV7+m8mjcV1ftCO5iv9p2PFG96eiph+rt95yMbSos0hlbqvJ6uikfq/xiu5bP1g4KW07wpdAiv9LP1g2FnZcxn6weD8fSjCJuv40Bm2PveUhRvabZWuu216Bl4+JJ9Ub7zs2sbu62ionikepPXZXMXd89/o3vp96HWd0tGav3it7ovfv2QV/ODRfXPVh/V/o1Hih/8ue6LX++++Gz96kfq/3AJY0il3uvnqmLBmIhC/P3/2Q9Nf6tynq1fPRhPP4qo7joO5Ib9XFX8UHOEARsdG7UDPHzeyzZv2+Sw+HK77D/8eEnNePFbUOu7JSO1/srvdb/1te63vhZ137rf03k1byyqfyq3DLz6XW2/8d++a04b+E/JDsXD9b/9WvPGonjjB82SRTntOx4u3vjB5o1FUTxcvfFhXv5Q1GSMOFxUalfEP6Xbx2KfrV8tDw/YLCpt3/Fw+Y5nO9IWcuyz9aulc8pXy8PH5hdFMTvtKg6k9rfvIEWZA8B28tBk2vxtQ8jsi7w8zP3DLWFtcQb215o3FuU73lUtFev0r31ejI2dO9euxSjz2frVxXSyLPUsbQI55Cu/B7W+WzJS6xe+2T33UvfcS1H3rfs9nVfzaFE9xd6WP/aZ/u/2xx4uHv1g99xn6lexfchH/dsPDvmtFsp5qf2xh8luH6yKh+t/w3aYjHEPnyudK5o3PvUXi7HM5tGieNW7WmJh9RSrtG9XQSxfrJT6qm+LoP+UHiL/Zs1nf1/YgdT+aU/vQMfJdGDMf28aQsYrJw87/rHa4gzsl5pHi6L4i83YF+WPfcYs1jS7U/MA38g6V9Xitoi2OqLr6bn5UvfcS90L34Ra3y0ZqfWXvtl9/qvd578add+639N5NY8W1T+Z3n6gErPjq55oP//V5tGiKIry7b88HdW+/eHi0Q+won7xibIoiuLNjV+OOKp5tC/zl+tXDTaMxkQdPhr8cP2L+q3YPh0rt6+p9JfrV83HKmPmVtCPvL+NEi7rwPnvf/LmsVLvQM/Jc73k7x1DiL9y8vCyf7wBPO02mjps7P9Wxdq100OsU4M1X9Xilhnds87GL0Gt75eM1Pr53+3+y1cOeTVvKKr3Tm8/UBUP1//a3rP90YeLoih/9JeGv9/wAbO04g0f8MqRR733zcVDT7T/+onyoSdaZkzc4YbB01tZQvujD/eWN28YmqA8sFwp9ZUy5pfqh4ZP6Ufe354PL+ZA0a7xb/NAz8lzk8nfe4eQ75879vCyf8a3UQN72qiKdWvn84DYOHveqiXUorieFWNpfD3/u1DruyUjtf7i17vPvdB97oWo+9b9ns6reUNRvYe9Ld7w/uHtex6r3vNC97ln6rcNW9q3Peg/nf7oPvdM/dBjDTm8fNszTjn0qBfGYx9Ub3jQH0KNWTr8mfoho6L2bQ+K4kH98bGEhx5vh4reX43bu48/XhbFVOOaSufWOW0p9CHy72L01ccfL4ticO8VHMiL+vjjJfWbOtBx8twLpDkbhpD9ysnDjn+MtrgDWwzO8m3PmMWaZlPf0tfY2PlTqxanRQ+xsyzYsy9073mMNGp8ffHrUOu7JSO1/u2vd7/xQvcbL0Tdt+73dF7N64vqp+mWZ+qHxojW698/bPzp+ceqTb/lY4+XRVEUD+qPTX/zQ6xy2rc+IDuMW6YymTGWGXOlz9QPFeVbn+l+44XuN94/BeLKtz5e9SaNpU24bSyK4qHH20DbaUt/+jG/Lc/UD421GM55UH+sP+SxSpt0BQfKokg51oGekyfLH3qseihYdWgIEdeJpuXjYeUfty3OwG5eP50RL7RvfTD8rd3u9u/cRjU5zJ63azHKpGeocCYhuHP321Dr+yUjtf5vL3W//jvdr/9O1H3rfk+8Dnh9qv5zD+pm4+Htjzwovv9nrt2E/a+fqYrtTnAKfFNzRFH34uFLt6X9kQflj3zq6k2Wr//2EtT6bslIrX/zpe7XnsfrCq+PvLMs3tRsOrb9vx4U/9v7rt+Eva/3VcWD+iOHuvQgt9yLhy/bln/wpuLPvbO9dnuN129Cre+XjNT6uZe6X30er9t6DfPvtc3Y/XpfVTyoP3x1M+7Yw/fWlo2v56DW90suav13Pvybn/vSd//T893/9//jhRdeeN3h6z89333uS9/9Ox/+zWtPt+AUclHrn3/2Kx/69Ivtl1/2nyyBF1544XXDr/bLL3/o0y9+9DNfvvZ0C04hF7X+w++8/OFPf/knPvSFJ57+PF544YXX/b1+4kNf+PCnv/yH33n52tMtOIVc1BoAAAC4XaDWAAAAQOpArQEAAIDUgVoDAAAAqZOjWsc8J/zaNsbTVEXVXNuIg0ijLW1dFmXdXtuMI0nDsfdMVh4eG3uHZ0rS5KjWMc8JNw9sZJq7YscZOhe27yxfN020dVlUzfy/+mCrDRdtS1OdOUlsmoPuw7G9uTMpTsXw8IXwz7Jz1Fp3BXEVc25T7e6vmyRHtY55TniwgG3X0XRSaSo2JPcMvLAxfCZr63I4uQJTHv0oZiK8SlvmliTBXTl23pVacCkWPQMPXwzvLDshkGBcGjTVtIV3cVFW1Y4LtNslR7XezW61PlJrVqg12fW4Ke9KbUkq9HhHjr26ky+o1pl6eA22eYcbvdgTYodd4ZTbJUe13n3fWg/WOYjDLgfnKA4Jopd1615S63L6cdlUxXBFycofimJX6uRwUSkd8d6URw8pS3n4aAmLTV2lLfYJbkXO1puhFj/8cLPAu3Gs1BXiY2OQy7tDU9f4K0lRQvA0McnLw2pIe20RfUGNKeu6WirW6V9bRmkkvD/crsUo0wyet3U5H232vJhyodbZsPm+9YgYOjSI496+NK6pxblmljOcVmR6kRHXyRj3cHLwVB2/eWZMB9pmZQn7+8Jt0b1g+nyTGWwOEnOHWeA9OZbaT5vuNZxP9iG13nSaGOTkYcc/Vlv4WOXbiXvKuo0/UzrjLKMb+Zkia3FbpOSY3oe2dlBhcqh1Nhx835qvLgp2Qb0QvRlOXDLgVTlaosTm0ZjFw9ll8oZwojhElnDRtqj2kJ5wF36xZtAZ2KxBFHhXjuUTsLHuIgcK/0xvzfJ2nCacnDy87J/xrRyr5iCeRmrkmUIPoThra1GLW6aCG6+HlRoQUGsQi1LrYNTOWnGI0szzbS5BX/mTc4hMEwuHyyXgsVPeZdvSyV7gu81z3QYzwmodCAxahd+aY8WAGf82D1yr1rtOE7ex9+xhcrjjn4BamwtcKfzBM6VzzrJotXZbpNrnqLUl1doJuZCjWh9931pcIg/juJYnJ1/mzgVMg9Mqx5ybyqoq6Xg2r9T14V6wS2wITXnGm+u0Rfh1WMAon28yw178NPW4XlAF3pNjWVGTa/2Gc8NnQSFXPoGqw6eJTU4edvxjNUxFwudilY7Gnileb8SptdMi60dfYsSoYSSBWmfD0fetx4vUYg6ndTQOxE4tEhpTh1jl6HHJTldmjGUGrVTs6kx5lp1DwLeoKuPbLVdpy7yvmPDsY9aYoeZ5qxdlX9+LY42lG/GzMmb2eFnX84w97ct+a7P2NLHn5Lw8rPzjtoWHnmkBxto67kzxAliRam2V6UqwskgG0mcJp2Sl2Tmq9e771jdLu+cnK0ldz+5qyfHcj2N3EB/5jC/wGL/ci4e77rJtSewsy54c1TpndpzrCU15h+vCfu7Dsbs4ulfafc8r4SXdhYe77pJtSfAsyxyoNYjknqa8pLgXx6Y7u9+Lh7vuvtoC1gG1BgAAAFIHag0AAACkDtQaAAAASB2oNQAAAJA6UGsAAAAgdaDWAAAAQOpArQEAAIDUyVGtdz8nPCkOe+BTAqTRlsDziS9KGt5IjqzcQp/xmcKYBNckR7Xe/JxwlQJuz2NqjSf1bi1nRQHjsxVCD1veZMNF23Luczg2zYzEf5fvWf7w5ERndbjFxR/PB6u1fMr25BXzIeHmRnA9clTrg/Nbx0L1UCQv2nMuhI3hItzqrJB6RzdfkG/A5duS2BOMebqEa3iD54G49OS6OE7ydEs83ng+M5BAc3IYOeTMjeCa5KjWu9mt1kdqzQq1jksVtVKtr9SWpAKisy3X8cbVPbM0TjJ1yxrC2a5OwOkzs6sSuzjOlRzV+uj81h1PHEiuR+cwEgmil3XrXujrcvpzqqmKIfsgK38oykivN2bIpO/pKeepNT2kLOXhoyUsOHaVttgTSDjlYKwZaknGDzcLpHmOr9KzTKKIY4yRKW/pzKkI3UWpKCE4tk1uwC1q8HgDXjiQ56asq6VinU6xBdHJTalqMcpcCJ570Xfz+iDxK51cyFGtj85vLXK72veFjSt9MQOY5QwnO1FGGcqejHEPJwdP1ekbWGKS0jYrS9jfF26L7gXT55vMYDOjmNLMArklV/AG7U1qr2ct142QWm8a2yaJu8VplDXg+ajg28k5NCXZjhmTnTGe6UY+JmUtbot8tXbE2tx87tdEQDQ5qvXB9635QoVf5tNB7s4H9DRU5WiJEptHYxYPZxfvGyLh4hBZwkXbotpDesJdQ8aaQXXBrEEUGFjlX8gbfC43lnDkQNGo6a1Z3o6xbZKuW5YbNb6Vo8IcLtOYiByTnTWeSWPd6ycZU+BlhvrBvDTQW72oCLg8Oar1bpRauydHPzvp6VCUZs4Ccwl6PULObDJ5LRwu19bHqvVl29LJXuC7zTPwBjPCah0IVxrbL+MN0cvj3zELpUW13jW2TZJ0y3KjAmptLnCl8AfHZOeMomi1XrX4tboLUp0+Oar10fetxYX7cHbVcsrgy9y5gOlUs8oxZbWsKnaj1Fw/6MO9EJzYEFJr48112iL8OiyrlM83mWEvyZp6XMWoAoljr+MNVhSJgHrW8m6ctYlcrgSqDo9tk/Td4jTKGv0qEj4Xq3Q0dkwGlrsRau20yIuEK3E3d/WPB1ciR7U++r71FOCbg3wdjU6xE54E7NQhVjn6JGaTCDPGMoNWKnZ11Nqycwj4FlVlfOfmKm2Z9xXTsH3MGjPUJYrVi7KvrQov5g1jFUico4yZ3VTWNbvSGLZWlXnzN2psO8KdvltUo9wBz0PPtABjbR03Jr0ATaRaW2V6aqu3y0C6GV2HcF+fHNV6933rm6Xd80OMVdHOs9nVkuNJzJwVrA2ixhSYzCjZxyUH/O0OIHA5clTrnNkxAyWk1odLzH4S8s4qjnZlu+/RJylxuS5NcDyDBIFag0huVY9ACAiFCwY8SAuoNQAAAJA6UGsAAAAgdaDWAAAAQOpArQEAAIDUgVoDAAAAqQO1BgAAAFIHag0AAACkTo5qvfs54fuhDxTc+nPXo57jO5dz+GOoon/MG9mWqz26+FDPnOjwnaRmTyJk5ZYjpiZwDjmq9e7nhIsHF2/gimpNH9g8Pdj5EPEgTxYeirk/tebei3LXWQ4nD+8wnkW9iXh7VKP2VHsWcIuLf2aeodZTR5jPWmcZUm7Ce9ciR7Xe+5zwti7Lct9jjjZP0/ufrxQogWnSulqaSqQo2JTJbyfnPXzK8Yxo9Wqrdjicp40gaS7OG5Zueqtr5FVc9FiebonHezL54YGE2fnEIXZGNDxYL0yOar2TfpjvG9R3ptbevHTvah1V5ylqPQ+gI/NBbJSla4SKlzyWqVvWEM76dVKNRupwO78Y0OSo1vvuW7dWBvh+wNmJBK3tOhFexxMZznmGyYEkUCRTE/op/OqKB5YCetNbxWsxDaPt6q9cAol0axUGs7P7kRNW2myaKnZbb7ZXl5HQMCCrdIvZCyc4nGlR4FIpUEhVkUDnuNKhM7U4XBgpJYr0lK5XeKYwpuzwiSD7RHvMbn7iblEDzZsuujUn+EI6UDbODe85OTqNU9Kcr0Jq29BU4Lxtc5pu3XQwkqNa77pv3XjJ5ws2t7PbnHq7eUqoFPGVnpDJdOAdy2qhx81zpDPDmJokmznZXZi7SGdZBuh28baoQ2aXBHdbaXa8eVFq7fXCCQ7Xs52c4Fb1Gm2CXuSww6kUWYJpHsiEc3aTrdZWCcZCOiIakbhbnEY500X0CW4Ua5rdyVHU8Y0L55rXIi+jNusJYaOeP5Z0P1NyVOs9963pwCJ/i+Fnnsmdcf7TDaFxXoTUWh5rfjBdSC8u9fg+fFE0TkIq4hdYW0sDrHa5k3VArYNNizE73rwFtTbv0Xtj4AiHW6uiwWYywcY2X9uzfDify40lHDlQeGZ6a5ZnV91vpaVEqHXibllu1Ph23QmuirVr7+xh5K2tRS1umSHmiw5nbc33hVxLclTrHahBak/iR6h1W5csxLRKrc3r361qbZw1ixfHevtogNmuM9R6ndlB8wJqTaN4di+c5HBTqkaNiCpk2It4mcjSwuFiiRY0fq1au7N0r7yOV0Mk6ZblRgXUOnCCq2JDF9ORa2tLrbeI6XgYO9zsSqi1QY5qvf2+Nbtgpu/bmvymi7zxttvhpuk8r/mKRBQo1VoHyoY3R6i1XCTYokU1rt9PnZTGeT63Kzw1THGxeLWOMjvaPE+tmeO9XjjD4dxKI8oR1WtdW5dlVbFb4ObKUB/Oipr6xzmQbiQjhRzGXa1KaOta1ruk1um7xWmUM11En+BGsabZngvj1NppkRG/Jh0hOlxdysym8QaDgRzVevN9aynW85a2Louq0t8O8bbrU2K8Gubr9SHKVFVMo4s13zLbotakFmaIPSv5JrgGyHYdo9ZrzY42j8uqH/4ze+EUh9NlEbVp3ieq15g8sFKNw6mRxipQe4hf1owuq8X1kBzhZgmNOoecE0G0LWm3qEZ500W35gQ3fOV2iuG2SLW2yjTV2qlcTXe8lZBqixzVeu/vrQ28K/2lFQAA22ite443weExTu+2wO1xyenidgdQvuSo1icAtQaX5lbH1tFq3e579ElKXK5LcVv4FoFaHwLUGoA4IBQumC5ACKg1AAAAkDpQawAAACB1oNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUgdqDQAAAKROjmq9L7/1IdDH+2398emeY+1yDn8oVPRPa7e1ZcMvd09s7E5SsycRsnLLEdMCuF9yVOtd+a27Tj1GeANXVGv1pOvDBIw8yth4TviiUWeo9VmN5UkJjMc6ryfenvCzyhMBbnHxh+0Jam0/pHvoH530IHXf5U2Oar33OeFtXZblvocObZaK/U87CpTgZJqKQZz8Rg6uE4hT6+MbyxMokIQP5w0JN9GTzjRzPosey9Mt8XjP6D4huEXzcdAEIyyPSucnDAMJkaNa76Q/1fadWHem1t75fZ9qzTJnHda+jbJ0jVDxkscydcsawvmvTqHVCbB5ajI/axxIgxzVet9969bKx96Pbzutn7XdypjJ0grSBJDTgSTUHJ8xs654eGsxgSOvxTSMtqu/cnHT3c8GhPL3ifR80mZRphnw3Jatcn1j2awXuEwJFFJVJNA5LmroTC0OF0ZKiWJ5xbVjTI8FF6WiBN5d2mN28xN3ixqD3qnarTm5FhJjsgnD8J6TrdI4Hcy5InyJJC4FQhc3eJR7muSo1rvuWzckd7o8SYkW06CTsd08LcUZ0taVFgVyjnnHslrocSp5spzlzOWmbOZkd2HuIp1lGaDbxduiDmEFslmQSKzlgRMaqyc2Mbev89i0w1SseziVIkswzQMdj9lqbZVgLLQi1l6Ju8VplHOqRp9cRrGm2Z0cRR3fuHA6eC0KKaw6R0Oraah1muSo1nvuW9NxTP4Wo92cTTpjDqIbrPPDWQGowtix5gfTxfzicpPvwxdm40SoLswDa2udx163yxUMXq6oaHrreuCExlqroqE5ZIJdKGSyWNuzfDify83wynSg5zGzPLvqfqsfRPVJ1y3LjRrfrju5VLF27Z09jLy1tajFLdPFinVgbX175KjWO1AnirE+63y1WKPWbV2yMNcqtTavwbeqtXHiRl6LWwaY7TperU9trClV45QYVciwF2khkaWFw8USLWj8WrV2J+leeR2vhkjSLcuNCqh14ORSxYYuZCPX1pZar9FSS6pVe1mZq/oXXI4c1Xr7fWs58Fkkl4fkZiWwttshr2muqfmqSBQo1VoH6+xY/SYBkwsV8+qESXC/n5pXjLlmbld4emIxQO5OLxKuLnOOayxvgDHhRXmsa+uyrCp2C9xcGerDVQyTOEEd6HiMHMaHpSqhrWtZ79Jsnr5bnEY5p2r0yWUUa5rtuTBOrZ0WWZFwe6tlweI1K7g+Oar15vvW+ip13NLWZVFV+hsq3nZ9Wk5xQ7ZeHyJd5NcWw9Yy+ltmW9Sa1MIMsWdG3wTXANmuWLWmtZR1XfF5VHvglMbSZRHZnewT5TEmD6xU43BqpDHPqiHDC7Y8Nu3LfstjldCo8S8BWDEAACAASURBVOsMQtG2pN2iGuWdqt2ak8vwldsphtsi1doq09RlGQpUQ1yWoNsOEiJHtd77e2sDb7WBmNI90ppf6L0FDl82ebcFbo9Lnqq3O4DANclRrU8Aap0Xt9qvR6t1u+/RJylxuS5FpBlsA2p9CFBrcAtAKFxwqoLUgVoDAAAAqQO1BgAAAFIHag0AAACkzn2pdVHghRdeeN3PC4CR+xoNVz+18MILL7wOfAEwcl+j4eqnFl544YXXgS8ARu5rNGCIAwDuAExlQHFfoyFuiO/Lb30Oe34Ie4c/ot36iKzAc5HXF4Rf3yYJfTznvY37Gag1UNzXaIgb4rvyW1tPAj6AI9RaPMZczGbXndz0I9aD9tyYWo978ycwpygl6Vs44J8QJ6i1+Sjv8NPFz/Ye1Boo7ms0xA3xHc8JFxmNnDxCGzhkba3S3tnZg66ClOuw067++Ok1fTo/9VklWrl0IxbNvrqF8XgP0z58bAwJ44Y6p3QaxsYLnkRQa6C4r9Fw9hC3J5Bk1JqtNpqqqCqWwOi6KykuDQs+uyW1FlmilvIsnco6tb6+m8OEE1WdgnmasBRbUGtwLe5rNJx+39rOmenloxv3bKo+WaGMn/GEduxaXpTQT7JNVbCMzupYvgqomvm9/IsUFa4uajuzh2b1oxXJTMuhlIL9jMyuPsgbXVfXyXK1z5dLs1Nt9ubNbtXNtFZhMlBr2mx1oizDiMI6I0UNRYN1FqqeiRoAMq2kGvnhGDMLDxkNcdJKBs8vcn6E1da8FJg3kkaefJkDtQaK+xoNF7hvPZyvXlC3rSuyuJ1nEzrdmSnlyYxilMAUwz92NmWYYFqSwN4Sn6jqlreLLLzzbKpupOt7B57HxmbICxGzLl2F5XO7NJEjm1vIPjer9rJdU1XwDrQ60VZrqwRjIR21to610CnfGQCmG61eMIr1+jSoneG+dlsUUmtz6WxuPP1bIFBroLiv0XD6feuBYc4j+ifVm12AWynlxRzA3zprGntnq/hJpYc/yC7uHOxWxwXY2C6T3nuzsisDlse465jG6bqUpabPzdLs49u6LKqqclePU9Vs/ccFxFg3kgO9TjTV2m51v5WWsiISvmzhcvlkANhu9HqhCIQYCjtuQT1lra31+RUYJxbmXXz/1v7JQXGoNVDc12i46BCfTmQZNVVh6TVqbZcQrdZTBHzcIt+LomKqi1HruNv5/SYdBrc8Nscey7ptI+8cLqj1Ymn0KqcoylKGigOBWdlkMs/HLNkW1ToY3LYW5gsOWrZwufyAWpsLXCn881WBXXv82nrp/FpipVR3qytYC9QaKO5rNJx937odvwbedfb8KtawC+s8NivrAB4pQcySzrHjZ1U1f6FVvXeFX1THKwhvF+s00+bpmLIsbQnkBZJqyqqaD7HqMqKsjk5YpTFfiQsH1mKzmW5kngRLvQOtTiSHLXi4rWup6qvUeslCp3xvAFhutHrBKNb0j9eaOLUOjxPlE7XV3Dibxht8AlBroLiv0XD+fWsSsxXrwykwOkbeqmpBOeZgXVnXTCdUCWreso+dP5IBXL6aFssju7pKf5fI227Esp25Vl5bOAaom8HBOw0r1FqXxmKm7iqZhFHkro33nXB1nSO95nTitC9xiFu14fR+KNpSt85CVb4/AGw3uhEOy9+Wf4xLj0i1Do4TUR7DDKSrc/ZUqe6g1sDgvkbDpe5b3zveEm1x6ZYlrfnV5ZUcHli1pW4nlxwAh7j1ZoFaA8V9jQYM8WOAWq/jAL8crdbsps2RpV5oAJx8Wzh5MJUBxX2NBgzxY4BaX5zbUCcMgEuBqQwo7ms0YIgDAO4ATGVAcV+jAUMcAHAHYCoDivsaDWdnhscLL7zwuuQLgJH7Gg1XP7XwwgsvvA58ATByX6Ph6qcWXnjhhdeBLwBGMBoAAACA1IFaAwAAAKmTo1rvyG99Gnt+bnsbP9U12frALfuBzxsLwg+Ik4Q+YfRWxzcAB5KjWu/Kb2095PgAjlRr8ozjiwuRTlsUnGxvTK1Zrg/1DOmUSN/CAX/gn6PW8in680breetp+w5kRo5qveM54SJvkp9sai1HqbWYjJpqfakbmsOzkKkUHH5ppzzMeg1rGjs/uJodFcyreBLrcm1dw8J4vOeBHz42+owyNFPKWI+sPzKXKAAXJUe13o49saSj1odMy/vUWtiwUNgtqbWba+sKjVin1td3c5hwrq2D0VnIrKxcLMMs5BokQY5qveO+tZZDEnae8xOLsFpT9SkRZWSNp+XjSR11YK5qmmrezTo2JPl+QkNmmGoOS+s4tY8upCtxiMzbHMqK2M/ILNYpki7b4UiRLZE1Ybk0OzNmbx5pGa9apt2kTTT7dKGjZRlGmkpnROg+0qyzUPUMGW/cX9EDySzW8Y8tiE5mzOB5RGIfnmu4Wrd1ORdpZeXGNxtAMuSo1rvuWw8zgxfsbeuKBqWnWYZOg5O08jlsmmmMEpiSuMe6ak2KXzZMLJQNiRq2Niwnt7WejvFM1bB6pkPsqlUVVhPs0kwPjDuwz82qVcptQzC9A63OstXaKsHQi6i1dayFTvnsmop4O3YgGcV6fWouo021Ns8js0Vxak3vHDHL2WUb1BqkQI5qvT+/9TAXkrNcqjdbUogJRShKJ3dx1zr2zvNbT63ldk8RlYzwNSGZ+PsPPDV1ZcDyDHcR0zizalGh2QSrNPv4ti776ICzepyqZus/LiDGupEc6HWWqdZ2q4W3tcM1ayxcLp9c06wYSKpYt0/NxbWzttbnUWCcBD0ji5T3lIbi6g3f/QDgBHJU64OYpkEZTVULzjVqbZcQp9aeXBuTrLkusdTaX6z7aj2812FwyzOsqnnaDkX1F9V6sTTW2KIsZag4EJiV7SVqaB64Vq2DwW1rYb7goGULl8sPqHVgIKliQ8Mpcm29dB4tY0TCgz1v2gbAFchRrbfft27Hr4F3nT3vktOdhNPclQedrfX6mJQgZk/nWPGm67rhO+EqgGmImKXWcmEmldWOhA8bytKZCLlnSDvKqpoPsao2oqyOTlilWR6gYYBwq93IPPGDd6DVWcJ99kp4aHUtVX2VWi9Z6JTPjXYi4YGBZBRrDyenNXFqHR4nS55R3SCPWn0xAMBp5KjWe+5b0/uB8jbmEDAdQ2jzT0UcRZmDeGVdM/1QJaj5zD5WfMR/y2VstQ0jzbGD11pl2CHTRypqanmGezF4R2GFWuvSbA/ISxPeHuksR17EZVXA96yzpn3Zr4qcqsWm2eG21K2zUJU/3SCQTVk1kLTZrn+MS49ItQ6OE+UTCu93w7vFclwdgMuRo1rvv28NcsS8u7qWwxdrp0RqF9fux9YFTQRgmRzVGoBtHCBiR6s1uzlzZKkXUmuEmgGIBGoNwAW5DXW65NoaABAF1BoAAABIHag1AAAAkDpQawAAACB1oNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUidHtd6R3zolQg9D3sNxvwg+y8LDybDJERzWFvx6O1no413vZdzeLzmq9Y7nhNM8RSMbp/rdU1jUCaYfl73I7UmXSqt0501mWSKPqM1u/5XUmiVaObSZR5O+hQP++D5NrUX+Go5KiYCLuShyVOsdzwkfsx2YORDXcZEFR1uXZRlRj0husee83dOuTcfqDI333mRqLktBtZ1TH9a9po08uQzLO3LpGX1dorNrWBiP178n5QMdTkLnEnDM0WLntAMuOar1DvphxS9EE1br/hyNOCNvW7pE4q4cmnz8RHdiHucVNrqJzq6QZnqdWqeeCDuc6OxQpnPQzoNmVIjMLlHkqNY77luzKN0w6tio9PMJ1hUPmJnj1s52SbaTlIsik6Asv5vPAW92H/4mlZZ1y0tz8j5OKT9FvbwotfYIxsGEGZ43+kKbqphSlMqV9b03WeYKFzcBjIPlNt0ua8IMDTB2wUreLKUl7a2Zzxxhhsx5SruNJ0tX9vP7Azr1vF4JixK4o3TXaNZZqDqCdCv315ppZEf/DntaaUmNycQczJZrrFOQFHLJJf69kaNa77xvTdIEj1Mumaq4cE8nAD1D9UQyH+AdzjLvGmqtyxeGWdM7bw1L9ytLM9VvqV3cQn6atnWlg7nSDMsbbL6X53kWTfbuW1vlG9eE3oWMmjHDA2wuhjnHs79qxOeee63LDPfOE6uaiVVIra0SDEdFra1jLXTK51m2rZETnkb29C/duDCZeC0KLZ4NZXbE+rivjdw5Oar13vvWVDj7q3A9pNnOYqw7au0dLrZPb93ZR+uVNbWyv72wMLlO5lgLWF+6nNPRWW0EvaFXk/z6//6bbERzAqvrvhnuErSw17XCV2arx41uk7n9Fb+va5rBTOACYqwbyYHL54i84rJ6VohulFrHWrhcvnO+L0wjO/p32NtaW0edC0GPGGeA7U8+fkGIHNV6B0oqCvKlM+M0M69M49XaiijFqrU6w/TMv0q67DDaVukiMQLbDNeZwm90xZBJk8WOVDWtC5Spbn29IZsWWFu7l4P25aGyvxDfOnLdy9bWeuFpH7hWrd2lHHHUGrVetnC5/IBaB6YRVWx8/9KNi2odtfilwQZ2CtL2ieoh1fHkqNYH3Lem7+dLTRXCMqYxX61Dh/MFfYxay/NgfE/iV2NwoFPzjq39RBUDk7glXezwpuaLId8M0xtarce9cmmys7Y2y2/r2lpaqnaJlTBfNHs60dZlWVWzbCzZT5od514+1RunAz3QO0d011slGI5apdZLFjrlc6Nn82KnkQ39y4hTa6dF4R99eVdQ1HtR1wBgJEe1PuS+Nd0i5k51VelO8Sq0ZB5O9/W/ZcbL1xet05apsLKqmMoUOqrIp2Zpmb3nXJRc2dCjSZNsMzxvGNJlzMH33mRv8aLLn3c2diTFTn6MV2uuN8o0d5Use8X+GoKx9FSO5Pbrc8Tpeq9qscnu1pl1Fqry23q4QSCbsmYaWd+/jEi1tspcpdZ6ZxkIg3Avk6Na77hvnQCxUalsEEFBsIVknHiIIYefI7bU7WRx7X5sXWn0L9hBjmp9a7R1yS7QcdoJLjnt3SVJXQEe0JtHt4eegYeWeqFhm1T/gs1ArW8BEobCWQfAArehTrjIBOuAWgMAAACpA7UGAAAAUgdqDQAAAKQO1BoAAABIHag1AAAAkDpQawAAACB1oNYAAABA6uSo1jueE34ae34hmsqvS7c+8OmwBwbjB6zJQp9wmcRgBeDmyFGtdzwnvDOfy3sAx6i1kqt9+qWfvB2cbG9MrVmuiaQfV5y+hQP+KD5HrZvKOA3d530ffc4CcFlyVOsdzwkXqX50GqWtJKTW5Bgp1+HiTnmY8hrWtJan5GBPdr10I9bleko7yaD3POrDx0afTYdm6hjrkfUTh2FlD26ZHNV6O/ZcdL9qLaRhobRbUms319MVGrFOra/v5jDhXE8Ho7Ng6bOInlqp3DQCYAM5qvWO+9Z2VkYWovTSLNaVCmTypHE8D6GO5VVNUxVmasUiTq3tdJy8NtkcmTc4lJWvn5HZ+kUk/bVDuSJbH3PUcml2ZsbePJU0kmZmtvIoi8WXabPleVmG4XOne9X4MVhnoeoZMnhE3wcyM6rhGk4CyXIjGg1xMjMGTwoyqD3X8AHf1uVcpB42WFmD2yZHtd5133qYTLz4cFtX5DqeZF6WyYNlgncyORklMPEJHUtvcLK5VaW4l7On2Rz6LqaZVdOZa32RNNe7pLAcZZdmtWXagX1uVk2XetRpdDL3DrQ8b6u1VcKiww3WWOiUz66pwkPC7AWjWK9PzWW0qdbmSWG2KE6t6W1sdZmnTlsAbowc1Xp/fuvh7CcTg1RvqZQqwbuIyfG3zvLI3jkqEi5DgEx+uAbo6KItA1YzeXtFJQTbFtNRZmn28W1dFlVVuavHqWq2/uMCYkYipgM9z5tqbbd60eGaNRbGd2hoSJi9UARCDIUdt6CestbW+qQIjJOgZ2SR8zuyFatrcMvkqNYHYa1P++++SOlco9Z2CWeotZzQrXXiXIYOg1vNnEPPZd3OdYRvFy6o9WJp0ye9WaUMFQcCs9JpRA3NA9eqdTC47Tk84KBlC5fLD6i1ucB1xolbe/zaeumkWMaIhMuetyUcgNsjR7Xeft+6pVnpralaXMcvLBnZBK9jgaQEMeE6xy4FmVnYc7S9liJjFlKWxkSom0mMKqtqPkSsCad6RJTV0QmrNKMtLAxgydtUtR+ZJ6sv70DL8+Qw7hCj1csOl6yx0CmfGx0cEmYvGMWa/vFaE6fW4XGy5BnVDdPosschALdFjmq95741Cf+qO59DjHUM4s2/LnFEaI77lXXNJEeVoKZA/1hHrdkxdMqat7IJXXxxyAheW83kLgneHlih1ro0uy1yDUpiH3LXxvtOuLxGCviLen7el/2qyKnadbgtdessVOVPNwhkUxw3uhEOy9+Wfww9jFTr4DhRPqHwfvfMhFSDGyZHtd5/3xrcPObd1bUcHle1pW4ni2v3Y+tCpBmAU8hRrQHoDhGxo9Wa3Wk5stQLqTXuCgNwHlBrALZyG+p0ybU1AOAsoNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUgdqDQAAAKQO1BoAAABIHag1AAAAkDo5qvWO/NaZs/VRW4flPsJPh5OFPlv0Bn6EDsDNkaNa73hOuHg68YHCwUu+1HSnsxwEJ9sbU2uW5ePivl1D+hYO+M+DOUGtydPo5wLNh5MDkAE5qvWO54Sft7ZT+TdOnIp40jAjPaZ34CmPsV7DGv/Pj6y+pG89U1Zk2Uo7UZT3JPDDx4aZG5RsxCIeZEaOar2DC6n1ybLo5EtWVihuSa3dLFtXaMQ6tb6+m8OEs2wdWAvLAqdzb9/Gc18BOIoc1XrHfWtz2u03NlUxJ80kb7tgekdx1PwRzyYtAoLkWBkSXKyrnGOuZd3qjM2hfIj9jMzME+mW7VCuyJNYV2S35dLsnJi9eSREoFxkZrBe9K2ommawNt1klMA9R0pzxWWdhapn1o4H3QtmsY5/7NW1kxNT1WKUaa6SpVqTpo7nC7QaZEWOan3YfWtLN9TbpqJT1ayN5lF6UhdpgGnGZr08XlGXtZ7mmlGRNYzIYN3ojNqmnbqKpmISM14vGKW5Daka8blZtUq2HetbFmyY67HV2irBuKKLWlvHWuiUv2Y8WL1gFOv1qbmMNtVa1eK2SCkvyeJNSyK+Sjn+AMDx5KjWR9+3FhtVVJNNRExxzaOUXDCsmZVo2Mq62FtTZNmFyTRNjzUxjdN2mo2jkzWfwU3p1w2pKnf1OFXN1n9rfCuqnt6aam23ut9KS1kRCY/o/cXyF8eD1wtFIMRQ2HEL6ilrbS1qCY8TXeS4U10pscfqGmRGjmq9g0PUWk//4q35/ZqIGrfUNb/XYXD1Ja15UdVXNU/b4XuIC2q9WBprSFGWMlQcCMzK9i75dq1aB4Pb1sJ8wUERvb9Y/uJ4sHtBFuvWHr+2ttR6i8LqoI6sAIC7J0e1Pue+tfdWRSOtLyqLt2TZINZaJLLNIoNO5DOirqm+srQnQl4+qbWsqvkQy04jyurohFVaqCHMAaaL3Mj8km/lfXwiiMQIeyU8tLqWqr5KrZcsdMpfMx6sXjCKNf3jtSZOrcPjxIH3vz3kALh7clTr435vHbVy5eE/c8FnvyX3/MTBU0BYlBlZ11gkjxXrqOnQyKrSa2uhELad8WqtS1tuSL/DrFZi18b7TviCb2nNZV2LqxbhELdqo8N6h9tSt85CVf7a8eBGOCx/W/4xRDJSrYPjRPlk7Aa59tftBODuyVGtd9y3ToTFtRpw7q6u5fBgqy11O7nkeDjErQCA1eSo1rcP1DqKA9x0tFq3dXlCx11uPOBWMQDXAmp9i0CtL8VtqBPGAwD3D9QaAAAASB2oNQAAAJA6UGsAAAAgdaDWAAAAQOpArQEAAIDUgVoDAAAAqQO1BgAAAFInR7Xe8ZzwHNj6tK3DciLh18PJQh8vegO/QwfgnshRrXc8J7xHP9T6VPaql85+EJxsb0ytWaKPiRSlJH0LB/xHwpyg1ubjwNWzxMUD+tP2HwCnkKNa731OeFuXZXnB5d/utaaU63CBpzzJeg1r2js/tZoddY30TOsSbaWdQMp7GPjhY8NMD9pUdvo0Yl3CvgPgJHJU6530M9kFNW3/5MSlYaG8W1JrN9HWFRqxTq2v7+Yw4URbB9bCEsGZmbjkRog1yJMc1Xrffetx+pDhQppnsY3e4uQPVFFANTuZmRDpdpbtUSZtDqVE7GdkFusUGZftUKRIlVhXZLfl0uy0mL158+JLVC1zbtIm8mTd2mZatZX7VK2Egx1HSnNDtOssdIaBkdYylBaT9YJZrOMfe3XtpMVUtRhlmsFzqdbmOBfbbuPR7QAcTo5qveu+NY3XzbNGU8lZ2tyipEVPUMaUZSfMngufpViKsq5QakZFW8CTWM/2TodYTTDMbComMeLihpZmtmLcgX1uVq3ybRuC6R3IxSqk1nEdF7e2jrXQKZ9dUxFve4NB9oJRrNen5jLaVGtVi9sipbL0GyCkJNM4fxMAWZCjWu+5by0k2hBuvd+0hTOKmJ67xRY1xcrCibx5KuDLgFpsTdP0eDzTON0EbaaYrPkMbko/O76ty6KqKnf1OFXN1n9cQIx1IznQc5Sp1rEdtyISvmzhcvlOp7uXVlMveGtg0afm4tpZW4tawuNEFznuVFdsR+vWPqLgIF9yVOsdqHnIFp64LTO9Ysqp2VrxmUU5wXn+ti9Fh8HVl7TmRVVfwDxth5c1C2q9WNr0SW9WKUPFgcAsr9757pLvwEW1juq4VfetlyxcLj+g1uYC1xldbu3xa2tLrbcsf1mNllRDrEHW5KjW2+9byylkek8/aOpxfeFv6ZpqmPVqIQ56S0wknNwGtiPhw4ayLG0JJCHJhn1zq6yq+RC7CSrK6uiEVZrVChoGsORtqtqPzItb49aBlqPIYdwhER23Tq2XLHTK50Y7kXDjamjsBaNY0z9ea+LUOjxOHMRgNHdFFBzkTI5qvfm+tb7e5zdbaTw5vMWKg1JdYlvo/c6CTvGqMLov+5bZ/Jne0u9dVXptLRTCbkK8WuvS7FbINWhB1Ep7z5EXUpd1IKmZOWralzgktuOGvfoAwvLCcMFCcxhUlfUlM9uNboTD8rflH+PSI1Ktg+NE+YSNa9Ea+smS3gNw3+So1nt/b30r5LASMe+uruVwR9lSt5NLRoEPcSsA4EhyVOv7pa1LtjbLYcY9QMSOVmvaDYeWeiG1zuEyD4CbA2p9X5AIJCbcWG5DnfANKwCyBmoNAAAApA7UGgAAAEgdqDUAAACQOlBrAAAAIHWg1gAAAEDqQK0BAACA1IFaAwAAAKmTo1rvy299Dnt+8nvgz4VPf7jj1qd8HWYYfrWcLPSxpjfw+3cALkyOar0rv7X1oOUDOEat+RPFNxi4fqLUz04PlnFjas0SjKgHV6dE+hYO+CP9HLVujLTZxkbzYekApESOar3jOeEid9Ock2HvGX6cWl96rpFyHbbhlCdor2GNi+anZbOj7GSO57Iuwdc1LIzHewj54WOjT2ND07N4G4nDsLIHqZKjWm/HnmfyVmshDQsm3JJauwm+rtCIdWp9fTeHCSf4OhjTdWIjPf1u4zm0IENyVOsd963tnJks/GiE1JqqT8sog5Q8NSBPLMlL6CeXpirMjJlFUK0XaycpI0UmxKDNZtZrlcNZu6Jq+PpFZHq2Q7khw5ZLs9Nx9uYNb3TVMtcnbWLYIXbvyDKM3JjOEFBjzGCdhapnyADj/gql41TDI5z5czbJvup10nHGDMLQgjhGracCsLIG6ZKjWu+6bz1MFF7st60rLWLkLtk8GzDhJwmzzBKYsISOpTcvqQ6Faid5r9lEaR5lCdj8Z4wrqoaVNB3iFC43WIbZpYmUydxC9rlZtcrzbQimd6DVO7ZaWyUY+hK1to610Cmfp1ifvW250eoFo1ivT81ltKnWcYNwt1oTB6YclABZk6Na789vPZzZSqzYp/MeYn4RAtPJXdylj73zUiR8Te2uioxHccgy1JYByxW8fKZxZuHCx5ZhZmn28W1dFlVVuavHqWq2/uMCYqwbyYHLvl1sdb+VlrIiEr5s4XL55JrGdqPXC0UgxFDYcQvqKWttHTsIlz3jbyQVYXUNUiVHtT6IaVaUwVUlnWv1UpeQjFo781h/nA6DW66Yl/xl3c7Tdvh24YJaL5Y2fdKbVcpQcSAwy6tnamgeuFatg8Fta2G+4KBlC5fLD6i1ucCVwj9fFdi1x6+tVwxChwi15mWurgGAi5CjWm+/b92OXwPvOnsaFtfoC8tBKxZtl6CXAtax8WodFQkPH9U1lZjey7K05zzuClJtWVXzIVbhRpTV0QmrNBbCFS4iNjntciPzZPXlHej5lhhhr4SHVtdS1Vep9ZKFTvncaCcSblwNjb1gFOsMGLs1cWodHidLnrE3ssObCtFwkCQ5qvWe+9YktKvuag7x0zFAN/9IxBGYOaZHvudll6BmnKVjSYzQlzddQowoqubPH6ioqeUK7rbgLYQVaq1LYzFTd5VM4iNy18b7Tri8jlIOsXtn3pf9gMipWmyax5gtdessVOW34w0C3bemG90Ih+Vvyz+GHkaqdXCcKJ9QZE+TEszzGoCkyFGt99+3vjcQ+zMx766u5XDf2lK3k8W1+7F1YbQBsJoc1RrwmD6PdgLCASJ2tFqzuzFHlnohtcaVIQDbgFrnCon9YfY8kdtQp0uurQEAW4BaAwAAAKkDtQYAAABSB2oNAAAApA7UGgAAAEgdqDUAAACQOlBrAAAAIHWg1gAAAEDq5KjWO/JbJ89t/LpXEXrOM0gB+lhQ9BQAVyBHtd6V37rr2JOTL/1ECf00bE5Oas0SdBQpP+olfQsH/OFzmlrLB8xPJ5f97Pu0/QfAieSo1rueE95UIj/BQXNH3MOk2rosy9COG9X6Bh9lNT9tlhOB7gAAGxhJREFUmhl/jQxK6xJkpZ3jyXuI9ylPJ58GtJFc2nTTDY5TAI4iR7XewXkzbdQ81E+loYkzG7V2E2SdJCsh1qn1NSxcQzhB1qFM49m67jK8envDFIDjyFGtt9+3DmmhTizIg4YsN7DYk2xR+5AKx3WPNIMWWLAcgzJg3093IrFhTO3kQO6BcD5G6/CqKrmNMgukPtws0Ew+LQK1phstd8kyAsaIJmvvadZZqFxq9ppuC09nWVfLw8H0j726dtJZqlqMMr3guR7O/JJAnW03epsHgGPIUa2337d2pwuexmpagZP9x4nI2VPmXbakiM1q0w5suU9Kb+tK79LP2DS/c2Tt/MAJY7ETcbheTDENCMzR034qT7YhmN6BlrtstbZK2LLkW2OhU77Va95YIndrjAThYf8I39KdtVrr61KvRXbyaeFlYaNxUQqxBhmTo1pvv2/tzRdyO9WGaRaT+s335KrM0ROhLdzqrbNK21C7J0j93u7C1Tl8tFLXrz1sFsjWf1xAjHUjOdBzl6nWdltUk9dEwpctXC5/fLs86jqyUo7sKXqI6AZrbS1qccv0PRK7tkYUHOROjmq9A0eujXlzXjyyQK+7p7mGFnUILHlj8qNvB8aptVF7eK7srwrMKL19eL+X8UUxU60DgVlZOFFD88C1ah0MblsLc3fnWAuXyw+otbnAlcIf7KluzdraUuuo5S8NNpDhzA7nrYZYg+zJUa33/N6aimDXdd3wnXAVk2TzWFXNM6a3pzOhd11T6QgufU8/INYRG9r5V1/kT7U9VLsxdQ6L49pakC4crt1iLz6bevStKtCL4tKwq3eg5S5yGHGLVYLR5FVqvWShU77Va95YsnQ0tqe81sSptdOi8I++xFA1L2UQBQcgR7Xe+3trusqdpzV7a2fcibX3HJYbZGVM95BirW5TDnHHmsn/sLWq2Nq6Mr6uFK7dVWtaOZOj4OHTTubyeD5cb2FRZKdweXHidxR117wvcZdbtW1gKb4ux0yKt1CV7/aaM5bstXVcTzlL61i1tspcodZW70eUAEAO5KjWu35vvZ6UlgV3FE80766u5fC+saVuJ5fstUPcCgA4nhzV+qKkpY9pWbOTAxpztFq3dXmCey/XayldWQIAGFDrE+ljjymp412p9QHchjqh1wAAUGsAAAAgeaDWAAAAQOpArQEAAIDUgVoDAAAAqQO1BgAAAFIHag0AAACkDtQaAAAASJ0c1XrPc8LBEeAHxOCewHjeAH2W7Q089CAFclTrHc8Jt7JT7DlPSY5gfyNLWHQTk4J+qvihXjvIrv2G3Gn3+RjPGg/smv4czLOIbO6jLcNIPPlfaFbaEnbIMDhBrUluBCtt8NLG5MlRrXc8Jzww3Zs5FwP0CaBoBonARpoyIfnhpZM0liX3R/zstl/Xg/2C7luBSF+22C3JP3KcZzxZ0zRd0PrxbCQzsdP4JcZRw+DwR+qbuWjjN94AOar1Dg6c7gN76pRNN3EaD4izsLeeb7wDtQ7sedvd57JBfE/JcXIYs3V7rys2DRh26dZURVWxtHKpDpPDhsHRg0Ne/eiE68GNt0COar3jvrU33ZPEhWU5Bz7Luh328GJHm6d7UqzKiOglVRxL0VucPIeyNLMKYYmxsrbOENsnvFLqVe5JN7OnaF1tlYDuC3Sfbsq0q87aOu3jzHfGTOj58/IOocY5TYu1QWgwXbjR3czxPO5YNdalY8yYj3CpbID22IWHQTer9dzYpiKnLE9uzq016zJmmDUbb4Ec1XrnfWtFeHHGTl811FdO9/Mw5cWKJNo89zUf1yItcVE1lhWGXV4V2hI+LcyTr5hLlU+MSn1Pdm1d6clWt1eXgO4LdB93lJgSh2lTT26TY3WlZsnan1dxiNYvKclxNhAZYMtlZRi3Y3ozmDKNFLbqXxzzcS5l9tuGXXAYkI1Mrantky/M/lVqTS8pppLiN94COar1Ze9b67k78NbdR14Ki31kgNW8ihz35JCrfrqr2uJVISzh19H0IPK35wRtRsCTwjVjAfZizikB3Wf7JDR/De0x95DH6lWV58CLO8Ra8LGmxdvQf1TxKznbMPNkmUwZ/vDPFGLkbGicS9klxZJh3dnDoHPX1i0/xLbWYdq5rOtKRV4WNyZPjmq9g2tN93ZwKji76fizuacsU4vlPAGaVUhr6XW0OtUW5hdthu/Jti5ZZCxltb6h7qMHepNxp4IM69bWm9T6aIfYCz7StHgbhrFYsgWfbZh1spABIt/HjPkNar1sGHXXGcOgW6HWW8Q0WOPyxkTJUa1PuG8tPpJ/22/MAo2NEdO9jtrN8edpt6YeL1aJnA4nTC0s11vcKrQl9AKWNo6FvA2fGJX6wikWIPMJL9p7gFrn1H3azPHTln7/V3jfmVBZN5JbAIY/r+IQ0gSjafE2zLV493cHw5S3m6qoqorVwt7HjPmQS63tUYYxjhoGjDi1dvo3/NsKU+LjNyZLjmp90u+thwvLKa5UkO+SVMEvVM0feBsXp/uOL2St611+4or9GmWg3uJUYU1Aelbo6BbPJ0al0pNWw9hvplR7/RLQfaYlLrR5UYdMQ4GrtefPCzuErqqcpkXaQI3vD5HDQVZE7w/pGuf3MWM+6FLrLLMMu8gwMLcuqLVlra3WxDnshkfkxhsgR7Xecd96AytOgzvBlKdbJb/uO4zIy5TrcScD1XNpIq6+Ey+nQI5qfVkSOWcuyh21+Y6aclmcGGNa/kzLmo0krda3FWpOHKj12SRxzoCtoPuOBf48nKTVGhwI1BoAAABIHag1AAAAkDpQawAAACB1oNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUidHtd7xnPDMEY8QZI8MBouPL74c7KHWx/YRfsW77SyA3zI5QU4kR7U+6TnhW5BPCTY3sqdPX3Vkmfm1nHxB1obVtS07RxhzVQdtnIyO9lu3azLilas8JldTnVs5C3rS8VsPThDOKWptPZt/YN3o9R4Al6NaXza/tUdblyIfRWBjRKKbSIN3wbI0VE2/qpjSG13FOUq/mwunq93v4ZQmI/FQ57Yuy5IbE2/csZ65lbNgMjYRv+EEsTherWkOIx1uWTt67Yer56jWOzhQkAJ76sQ7VuK+bQbvgqbXKutWDMqrOEcn+rowdzUZ6SBvWbd8YwJqnfRZMNuaht9wglgcrtYLuUvWj17LrhzV+oT81iTQVJZzzGPO0ugFSTarNSmWpN3llVCrvH2mUkVEz9xzHkFN1S9zY9T6TOeEBr7XhLKuK9VYvdF0i9hYMw8z0+JrD05GJIRG5t8Fa3mPGybxqqdRZKyshxTSMuOy0WXcUjH21HA12hX07c2cBYn5DSfIkScIh93uCF8VOWodWGcb8t/mqNY771srwsvH/hCvT1eq9dy7vNh+3qDDwbDK24dvX9hTBNhkLt5LO8edjEKNJUbNGe+tjfqWvPYVsWf+c1XtQb9VNBHyQhOs0SAWgsJmPYq4BMyFsGONLjP6yu9ov12ub2/mLEjMbzhBjjxBaKco/TaGAj3Ei4RPrRMH6sV1lmp92fvWWnoDb9195DXfgmix0eact+NH+nx2S2v0t2GredxfwzneZBRqAvWhOe+MCyNOWbdWddZktK72hUCfWjw41tIamWBMs6hqjq6Jr0RKMhM6Cx02TRdqGnI62mpX2Lc3cxYk5jecIAeeIGNlpiAzY+Qe5ug1duEjROyZpVrv4FpqbUdhgvOUGujePlHz1HTSynmqiTqpznOOMxuFmhA9GemCt09Ggdp9v7V1aVwLbZ2MDD9pZ7LlB0d3pf2WBm3tjjbbtazWN3EWpOY3nCAHniDzRtKzGraO523ReKVhbd113Sn3rTv/HGOXTOrK7CC11pElY73r7UPHVlOPl83OnuP5UNZtP0+1dWnMMhdzDjthZ9NCTYibjGTobJoIhK+syWhd7b7fxNIsMBkxw6hLaKBPN8e/9JETzvTe6bL5O9FsKrVVx22X79tbOQuS8xtOkANPEA7t0pZ+11Arv6PW8+RpfjQNh8EPOar1Sb+3Hq6RpgBKQb4nUgW/XDJ/4G1cnKc6flEvLseXvl8zV2surehGNuB5YOcqzgk03WtC5GTEKlQOLQrdNOaA+NoXrnIGL8+/XHOsnSss69r6yqvRHFm1PXV1dIvXZaR+UeHU0daAY7/IC/j2Rs6C9PwW8ApOEK833RMkAJ2e1NWJo9YBJrsyV+sd9603sKK/b41297PM7tg5t8n6WSV79p8F4E7RwexY7GvTHNX6skCQAsA5yYEuAeAQNl/HOd81gFqfDma/AHAOAADEALUGAAAAkgdqDQAAAKQO1BoAAABIHag1AAAAkDpQawAAACB1oNYAAABA6kCtAQAAgNTJUa13PCf8gji/kF8m8OxZ94ADf/OMn1AfxfgkpNUdCgC4Q3JU6x3PCe+6btbR6cGwQXEST7eOFrILqfX08FyRoWatuaz6bUet99Ft03vK7+cz1HrqWZl5Qo4B4znwAIBrkqNa731OOM9UtDSZbV1rblbrBXSGn3ZI+TckAxLJatbaHt9eJ8NSJkvJucXes7m3P2XYr7JSfUzcPW8ln581DgEA68hRrfdyP2rd18EleW9eh91qnYdAMCm2dflwteZlG/mNxjesA5DoA4AkyFGt9963dtXazAFnqldT9VnbZKiRliDSrJvRaavGuUJdC9l/TnJbVaWMi1oq4eQZZInodDpbukaTNZP3plqThodzHcrCzS1GQjwr41+gE6kl1nYdtnD7mkugLYg0Eh4oymrsUnzCSNZMt0u1zuXeBAApk6NaH3XfWv3J86urDKxk/m+qgn5uZndnUy9J8c7ClUaNbHLXtRgpjR3tk5us1vHtY03D+ozl19VpsBcj4bzhK2ywqtOiY8hQuBO1ZvHtrlqbfW3mlRbGxHSo11gzi88wGL1ryaGsti6toQoAuCI5qvUp961l9NbUJKuISahECfNbIyO9Cld2lizFpXbv2rqsKlN1i8IoKWTD+FFVuSEAcxXOrmm0riufhW2wq+u36i/T8TXqik5U2wNra9ELcjFtLq6dtbUeNkZjF5ivSsy1NfVhWdcVIuEAXJ8c1Xon+sYv/2vay1PH7jS1FiK4Qq0bVzCCdTlqXZRlGVJB7Uiz9kW1dmwI3ffuLwvox2TLuk5U2+PVevvaemnYxDIethz0PvP2OQAgmhzVet99axZkDEXCba1Vx7EZnK81aSScfeBEwqWyLKp1Uw1xz6qZmsW+czaV4LWO2tzU9GKBWS2C/HMwd4Var7DBqm76zjuxUG6J7ETvtgIZGrybzL7m9603q7XTWCMSTnpWWDoHvdVBGy8GAABHk6Nab75vLe7nTtFbqknmF5RUnNKcdvm3hWouFZX5E2irxoXJfTSI3hrmAVRqsRPOFkt9ulGEHsbtpFDpmuGKYVGt422wq2uUC/WWQCcuqzWptqyqcC808d8JX+pQo7HOfWvLK5b3zGEBALgqOar13vvWl8YLwx5YPkKdF4ddPkETAQAL5KjWt8bZag2uQzv+/AtaDQBYBGqdPlBrAADIHag1AAAAkDpQawAAACB1oNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUgdqDQAAAKROjmq9N7+15MznWxxc9k1kaDjv2Wo3+sv1pMz2jNk2tOjTVfGQGABC5KjWe58TTnHSRh4GTyxhPSN7bXE0YfPu8o6HZGpUKTs6NauvnOSvJnvOyInENZtlUJk4V/W2qLV/hpyg1ubD0O0npNtPigcgTXJU693PCdfpDi+j1jSLw7YamVqfPD9tqKI/ZMzgWevU2jLf5UrXX32Rum0B6pjNE7Ww5CUnNnLb2tp7FvrhwR7S+vk0MTcivxi4MXJU691cW623V5m4WvfN4pFwmaG0qmbvr82HcVdq3TA/LGb0OoqtkfBwnrHDoGcGzfeqNyKZCrgxclTr3fetLbWuKx5Rm1I2sJiuDFXaAToeN11QayeJpL09pNY0ITVZjFhmi40iUXVRNbR21XyViXL2UlP1ySZlFsrZlj4Tt9GImPLJAb3n3Tbq7rMKNBouxwMXBCVOgUSi8zbTbDoepB3GknvBPMdmwzziAbadNs0Z6oY4OllBDe+pMgNZQce+Zg4SG9u6JGctdBukT45qvfm+9YhWazqv0sTRdP7Sc2tbV+SKf56t+LQXioSTz1UhznbrvjWZccu6JcaaZvPCO08VZKJryx7hpcmb6l71WDHTqbkfIssfS2K7O12jDOt0ga4c6vEw1cUvRPQAcK6jLLMtfZd39SPNc8awMT65B4yhZfpTt51vXDZPleneD5q8Ia/55FhfSgcOQFLkqNZn3reelEQFJzls7qGaKWLc9rfMvBtvZFq35XQxEt4baq3bp4p1FH5RrV17TDPauqyqqlBOpb71LypC5bd1WVQVv69rd43nH749sHiV42GqTJaqlq+8CzyzWcFc69TFSYR5rs2hhT57OzbNHerm4tpZWwtL/NNHQQ43xX7ayMcMbmGD9MlRrXezSa31ZNDWJQvrLaq1KsJQKWMmslaj0WptTrAHqLXlpfnTqmHtHSPgxC75Pqr83uNluTxPX0StzQFAP6NxGmG2Wlvr1e5etbbNi1BrW/fi19aWWkdqqanB5kbeM1BrkD45qvUp963Dai3j23Jea+d7xnRPMV+ayml+QzqwPaTWzfgtL1qONJttbGp1N9BahHn2KC8N82h/d5odUVVV8H1M+TSIasnb3Eatyla32g2PVmtzAIzfhTciBNJsM+AsjI00b0EjRbfyAaoj4dqfgREXodZmmWb4mm0cjzI3Su9ArEHq5KjWJ9y3XlRrI6RIN5VVxaVtDPjVwbU133vtt8x0hNvRXFX6vJGs4lRDho1E+FVJAS/xxtK7jNb7uPLlBQSZt42uWVZru+HxkXB7AMwtMdbIs9mkLCuEwFu2ZJ47htXhU1jeG1rOmDGX1rFqbZXpSCwd2WwcGCeJ8jQACZOjWu++bw1OpT3tWWb3hXf9liK3ZCsAaZKjWgNwH3h311MDd4UB2A/UGgAAAEgdqDUAAACQOlBrAAAAIHWg1gAAAEDqQK0BAACA1IFaAwAAAKkDtQYAAABSB2oNAAAApE6Oar37OeGCM5/9cHDZ9uMfE+O8Z5kl/jQR+hhOPE0EAMDIUa03PydcJe6bHth8AbVmT/beKjnec8LTkbDJx1ZeESVkK3XtymrdV+8PlxPU2n7uunQy3zOh0QAAmMhRrc/Mb300ZsbM7bP5YsbMA9lQRX9IO2TMrFWWB5ZHUn14iknHMXdgIEHLsdaRSx1+2acuhUSeTazsAUiOHNV6N9dW6+1VJq7WU8ZObzXdZ8qkyZ5WueGaas0GTTgh1YFVsgudKWu1zlFGd8VTvQFIkRzV+pT81nXFw4hT1NNIGSnXin4iP7K3p9bbM2YKZaCJi/miTIdN+UZa2PA3qX05Y+bspabqszPKtJKzLX3ma6MRMeWTA3rPu23U3WcVaDRcjgdSIA87G4LopI+URVkGmwtiFZYQiTbpLmMBWFkDkCg5qvUJ+a1pNmiaG5hqCc3aO87KFVnP6JhkJ3JO60g4+VwV4my37luT5MlDputZYrXZvPCus9RabPXsEV6avKnuVY8VVw1PykzkNqJ8olj2UpJ0jTKs0wW6aq3Hgx4zunBTrc2ilMGmyMrrr6Jq5GUaKWsaErhtDUCK5KjWZ963npSEz4rq+2lsuqWaKcKQ9rfMyLralE1v+3IkvDfUWrdPFetA6aJau/aYZrR1WVVVoZxKfetfVITKb+uyqKoqEMgYG+/5h28PrK3FeJCLaXNx7aytRVH+WDIg3yerq/FwQ62FamN1DUBy5KjWu9mk1noCbOuSRTIX1Toc6uzYhG5rw3q1NjXlALW2vDR/2i8C2e3qhmww3keV33u8ZGpk36U9Wq23r60ttd4ipmPhXnh80SUAgKuSo1qfct86rNYyvi3nTRKzpHsKPTeV0/yGdGB7SK2nb3mZv58azGYbm5rf6yQNCUbC5UXK+MGwhu7vTrMjqqoKvo8pn8aNmW2qjVqVrW61G+6pNb9vvVmtTYOXFsRirMmrKHZ4UyEaDkB65KjWJ9y3XlRr8wtl86ayqri0zeHLoFqzvdd+y0xHuB3NVaXPG9l3tkRDho1E+FVJAS/xxpIbuOb7uPLlBURBb1KrrllWa7vh5njgg8ZcWseqtWWwrdaON1X38SIh1QCkSI5qvfu+NTiV9rRnmV2VWW29Cy8AAHDJUa0BuArt+PMvaDUAYC1QawAAACB1oNYAAABA6kCtAQAAgNSBWgMAAACpA7UGAAAAUgdqDQAAAKQO1BoAAABIHag1AAAAkDo5qvXu54Rvw0sUoTnz+Rkryk7EjDPqjnq2NgAApEOOar35OeEqV+GqRyobau0UeDmZnJ6udS0zzqhj6ZFh56j17MTg48y9B6EDAECQHNX66PzWkQTW1oE0IUfj5Im4nhlHPzR7+XHc27oviOGqPn8azdbSsfRWeAApAGANOar1bu5ErVUzrnTRcKh6rkh1dRiBC45AmnPk9gAArCBHtT46v7WdVlJtIxN3/5mrKk3V58pUORGHoLXKQckkwAvIFmJvrRZXMcOULV4LlTyRTXI0j+SS5IF+QxCdxJSyKKtpZvC8rUviJ/5xWK2RmxIAEEuOan10fuu2rsgyUSoB2a0cbwfLGV/LJJX4ObMyz1RN5W6sVVtCo6+scr3EvIoZpiW8FlettXm6CVoQTbU2i1JNM9Wa3pyWO+g82SQSjkzSAIBoclTrM+5bq8VkvyxTE3dVWVN0IAQ9LQ/VKo3DhIVaIuLZ01tj3XkNM1jh3FeN9U4siIV5siRzce2srUVRftMkvGnW1/j4zmNxdYVIOAAglhzVejdc1fqvE82RUr7sLqd5vt+vtL6HvEkmdTGmJa5MxqytL2CGaclWtd6+trbUOlJM+SXBglov2AYAADY5qvXB963J9DxHOtu6lvJCo6nxX+9yZFIGlqUikkronlRItRxdxQzhIasWEl7mBZpqvaiVcWptNs3+0Zewz4+EcyOwsgYAxJOjWh9/33r6CS35wY76/S2duPsP6W3ctTJpfpPLtoR9Ware9p3wE82Yq/XUmpRICjTNW/Od8AW1tppmq3Vn9DY9eN5OPAOpBgCsIUe13n3f+l5I4jdERxvRLv7eGgAAbo8c1RpMXP1XRGcEhKeff0GrAQB3A9QaAAAASB2oNQAAAJA6UGsAAAAgdaDWAAAAQOpArQEAAIDU+e8N8OkCAK4rjAAAAABJRU5ErkJggg==" alt="" />

  注意红色方框圈中的类,StandardWrapperValue类中的invoke方法225行代码如下:

                        filterChain.doFilter
(request.getRequest(), response.getResponse());

  在StandardWrapperValue类中并没有直接将Request对象与Response对象传递给 ApplicationFilterChain类的doFilter方法,传递的是RequestFacade与ResponseFacade对象,为什 么这么说呢,看一下request.getRequest()与response.getResponse()方法就真相大白了。

  Request类

public HttpServletRequest getRequest() {
if (facade == null) {
facade = new RequestFacade(this);
}
return facade;
}
public HttpServletResponse getResponse() {
if (facade == null) {
facade = new ResponseFacade(this);
}
return (facade);
}

可以看到它们返回都是各自的一个门面类,那么这样做有什么好处呢?

  Request对象中的很多方法都是内部组件之间相互交互时使用的,比如setComet、setRequestedSessionId等方法 (这里就不一一列举了)。这些方法并不对外部公开,但是又必须设置为public,因为还需要跟内部组件之间交互使用。最好的解决方法就是通过使用一个 Facade类,将与内部组件之间交互使用的方法屏蔽掉,只提供给外部程序感兴趣的方法。

  如果不使用Facade类,直接传递的是Request对象和Response对象,那么熟悉容器内部运作的程序员可以分别把 ServletRequest和ServletResponse对象向下转换为Request和Response,并调用它们的公共方法。比如拥有 Request对象,就可以调用setComet、setRequestedSessionId等方法,这会危害安全性。

  

  

  

  

《JAVA与模式》之门面模式的更多相关文章

  1. 设计模式---接口隔离模式之门面模式(Façade)

    前提:接口隔离模式 在组建构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接接口(稳定的),来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式: 门面模 ...

  2. java设计模式5.组合模式、门面模式、享元模式、桥接模式

    组合模式 在面向对象的语言中,树结构有着巨大的威力,一个基于继承的类型的等级结构便是一个数结构,一个基于合成的对象结构也是一个数结构.组合模式将部分与整体的关系用树结构表示出来,使得客户端把一个个单独 ...

  3. Java设计模式(12)——结构型模式之门面模式(Facade)

    一.概述 概念 简要示意图(没有一个统一的UML图) 角色 门面角色:门面模式核心,它被客户端调用,并且熟悉子系统   子系统角色:子系统,子系统并不知道门面的存在,门面对它来说只不过是另外一个客户端 ...

  4. Java设计模式(一)外观模式(门面模式)- 结构型模式

    模式的定义 门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式,其定义如下:要求一个子系统的外部与其内部通信必须通过一个统一的对象进行.门面模式提供一个高层次的接口,使得 ...

  5. 外观模式(Facade)(门面模式、子系统容易使用)

    外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式.该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低 ...

  6. 深入 Laravel 内核之外观模式(门面模式)

    门面模式核心内容: 客户端与子系统的通信通过外观对象进行: 外观对象封装一系列子系统的具体对应方法,对客户端只需暴露一个单一的入口方法: 客户端通过访问外观对象即可调用子系统的基础方法,无需关心子系统 ...

  7. java设计模式之外观模式(门面模式)

    针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下. 一.概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计 ...

  8. Facade(外观模式或门面模式)

    常用的模式之一. 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 完美地体现了依赖倒转原则和迪米特法则的思想. Facade模式应用场景: 首先 ...

  9. 重学 Java 设计模式:实战外观模式「基于SpringBoot开发门面模式中间件,统一控制接口白名单场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你感受到的容易,一定有人为你承担不容易 这句话更像是描述生活的,许许多多的磕磕绊绊总 ...

  10. 设计模式 - 门面模式(Facade Pattern,也叫外观模式)

    简介 场景 将系统划分为若干个子系统有利于降低系统的复杂性,但是这会增加调用者的复杂性.通过引入 Facade 可以对调用者屏蔽系统内部子系统的细节. Java 中有多个日志库,例如 log4j.lo ...

随机推荐

  1. 玩转SSH(五):Struts + Spring + MyBatis(注解版)

    本文将在 玩转SSH(四):Struts + Spring + MyBatis 的基础上进行一些小的改动,将原本是 xml 配置方式的项目,改成注解的配置方式. 要将项目改成注解方式,一般是将在 Sp ...

  2. 3.Maven坐标和依赖

    1.1 何为Maven坐标 正如之前所说的,Maven的一大功能就是管理项目依赖.为了能自动化地解析任何一个Java构件,Maven就必须将它们唯一标识,这就依赖管理的底层基础——坐标. 1.2 坐标 ...

  3. 搞定:Enter passphrase for key提示

    使用ssh-genkey生成公用key,但是自己使用时会多次提示,Enter passphrase for key,这儿给出如何解决. 在${HOME}/.bashrc中增加如下代码: alias a ...

  4. 浩哥解析MyBatis源码(七)——DataSource数据源模块之托管数据源

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6675700.html 1 回顾 之前介绍的非池型与池型数据源都是MyBatis自己定义的内 ...

  5. 看Lucene源码必须知道的基本规则和算法

    上中学的时候写作文,最喜欢的季节我都是写冬天.虽然是因为写冬天的人比较少,那时确实也是对其他季节没有什么特殊的偏好,反而一到冬天,自己皮肤会变得特别白.但是冬天啊,看到的只有四季常青盆栽:瓜栗(就是发 ...

  6. python str.format()

    python中的字符串格式函数str.format(): #使用str.format()函数 #使用'{}'占位符 print('I\'m {},{}'.format('Hongten','Welco ...

  7. 学习vue 20天,我写了点东西

    往昔 最初团队里使用Angularjs进行开发,刚开始还好,到了项目后期越发感觉Angularjs太重了,以至于后来重构项目时,毅然放弃Angularjs,投入了Vue的怀抱.除了组建团队时,是我搭建 ...

  8. openMP编程(上篇)之指令和锁

    openMP简介 openMP是一个编译器指令和库函数的集合,主要是为共享式存储计算机上的并行程序设计使用的. 当计算机升级到多核时,程序中创建的线程数量需要随CPU核数变化,如在CPU核数超过线程数 ...

  9. 【2017-04-18】Ado.Net C#连接数据库进行增、删、改、查

    一.简介 1.ado.net是一门数据库访问技术. 他可以通过程序来操作数据库 2.类库 Connection 类 和数据库交互,必须连接它.连接帮助指明数据库服务器.数据库名字.用户名.密码,和连接 ...

  10. websocket技术分享

    开发环境: spring3+tomcat7+spring-websocket4 运行环境: windows.Linux 一.背景: 产品将要发布的消息或其他需要让客户提前知道的消息,在客户端和服务端建 ...