我们继续上面的几种模式:4.组合模式将对象组合成树状结构,表示“部分-整体”的层次结构。特点:灵活性强应用:对象部分-整体层次结构,模糊组合对象和简单对象处理代码实现/**组合模式**///继承模式classUserBaseInfo{private$name;function__construct($name){$this->name=$name;}publicfunctiongetName(){return$this->name;}}classUserextendsUserBaseInfo{private$login=false;publicfunctionsetLogin($islogin){$this->login=$islogin;}publicfunctionisLogin(){return$this->login;}}$user=newUser('张三');$user->setLogin(true);if($user->isLogin()){echo$user->getName()."已经登录n";}else{echo$user->getName()."未登录n";}//组合模式类LoginInfo{protected$user;protected$login=false;publicfunctionsetLogin($user,$isLogin){$this->user=$user;$this->login=$isLogin;}publicfunctionisLogin(){return$this->login;}}$user=newUser('张三');$login=newLoginInfo();$login->setLogin($user,true);if($login->isLogin()){echo$user->getName()."Alreadyloggedinn";}else{echo$user->getName()."Notyetloggedinn";}//部分可以替换,但不能用继承类admin{protected$level;function__construct($level){$this->level=$level;}functiongetLevel(){return$this->level;}}$admin=newAdmin(1);$login->setLogin($admin,true);if($login->isLogin()){printf("级别为%d的管理员已登录n",$admin->getLevel());}else{printf("级别为%d的管理员也已登录Notloggedinn",$admin->getLevel());}?>上面的例子分别展示了使用继承和组合来处理新功能。复杂的时候,组合模式的优势越来越明显。比如上面的登录信息,如果要增加登录次数、上次登录时间、登录ip等信息,登录本身就会变成一个比较复杂的对象。如果以后有新的需求,比如好友信息,用户访问信息等,如果要继承的话,用户类会变得很大,之间难免不会有冲突的变量和方法父类,以及很多外部访问用户类的方法也变得很费力。采用组合模式后,一个类负责一个角色,功能区分非常明显,易于扩展。5.外观模式(门面模式)为系统中的一组接口提供一致的接口特点:向上抽取,通用应用:内部接口众多,统一接口调用/**有财网公共类示例代码*外观模式,也称为外观模式**/类操作{publicfunctiontestPlus(){printf("plus:%sn",(1+2==3?'true':'false'));}publicfunctiontestMinus(){printf("minus:%sn",(3-2==2?'true':'false'));}publicfunctiontestTimes(){printf("times:%sn",(2*3==6?'true':'false'));}}classTester{protected$_operation;function__construct(){$this->_operation=newOperation();}publicfunctiontestAll(){$this->_operation->testPlus();$this->_operation->testMinus();$this->_operation->testTimes();}}//测试用例,测试所有接口$tester=newTester();$tester->testAll();?>Facade模式估计大家在实际代码中都会用到。当接口较多时,将功能相似的接口封装成一个接口,供外部调用。这就是门面模式。6、享元模式使用共享技术有效支持大量细粒度对象,使用一个共享避免大量相同内容对象的开销。这种开销最直观的就是内存丢失。特点:高效、共享应用:系统底层设计。例如字符串创建。如果两个字符串相同,则不会创建第二个字符串,但第二个字符串的引用直接指向第一个字符串。$str1="abc",$str2="abc"。然后只会在内存存储中创建一个字符串“abc”,$str1.$str2将指向它。7、代理模式为其他对象提供代理来控制对这个对象的访问,即为一个对象提供一个代理对象,由代理对象控制具体对象的引用。能够协调调用者和被调用者可以在一定程度上降低系统的耦合度。特点:耦合度低,独立性好,应用安全:客户端无法访问或受访者想隐藏自己,通过代理访问自己。代码实现/***代理模式*///内部对象类User{publicfunctiongetName(){return'张三';}publicfunctiongetType(){return'付费用户';}}//代理接口定义,比如一个openplatforminterfaceUserInterface{functiongetName();}//代理对象类UserProxy实现UserInterface{protected$_user;function__construct(){$this->_user=newUser();}publicfunctiongetName(){return$this->_user->getName();}}//内部调用$user=newUser();printf("用户名:%sn",$user->getName());printf("用户类型:%sn",$user->getType());//外部调用//$user=newUserProxy();//printf("用户名:%sn",$user->getName());//printf("用户类型:%sn",$user->getType());//无法访问,及时知道内部对象有这个方法?>3.总结代理模式、适配器模式、门面模式、装饰模式的区别:它们都封装了一个内部对象,调用内部对象的方法的区别:各有各的特点和应用场景,不能相互替代其他。所以大家在使用的时候,一定要仔细分析适合自己的。关于模型的选择模型的选择应该根据实际业务需求,通过对业务逻辑的认真分析,然后根据模型的特点和应用场景进行合理的选择和区分。大多数情况下,业务场景决定了选择哪种模式,而不是选择哪种模式来实现一个业务。在少数情况下,几种模式确实可以解决问题,主要是考虑以后的扩展。到目前为止,我们已经了解了7种结构模式。在下一篇文章中,我们将继续介绍设计模式的行为模式。先来预览一下行为模式的类型:模板方法模式命令模式迭代器模式观察者模式终结者模式备忘录模式解释器模式状态模式策略模式责任链模式访问者模式
