当前位置: 首页 > news >正文

网站建设装什么系统征婚网站做原油

网站建设装什么系统,征婚网站做原油,建设通网站有法律,商务网络设计实验报告目录1 适配器模式1.1 定义1.2 应用场景1.3 适配器角色1.4 类适配器1.5 对象适配器1.5 接口适配器1.6 实战1.7 源码1.8 适配器与装饰器的对比1.9 适配器模式的优缺点1.10 总结2 桥接模式2.1 原理解析2.2 角色2.3 通用写法2.4 应用场景2.5 业务场景中的运用2.6 源码2.7 桥接模式优… 目录1 适配器模式1.1 定义1.2 应用场景1.3 适配器角色1.4 类适配器1.5 对象适配器1.5 接口适配器1.6 实战1.7 源码1.8 适配器与装饰器的对比1.9 适配器模式的优缺点1.10 总结2 桥接模式2.1 原理解析2.2 角色2.3 通用写法2.4 应用场景2.5 业务场景中的运用2.6 源码2.7 桥接模式优缺点2.8 代理、桥接、装饰器、适配器 4 种设计模式的区别1 适配器模式 1.1 定义 适配器模式是一种结构型设计模式 它能使接口不兼容的对象能够相互合作。 适配器模式的英文翻译是 Adapter Design Pattern。顾名思义这个模式就是用来做适配的它将不兼容的接口转换为可兼容的接口让原本由于接口不兼容而不能一起工作的类可以一起工作。 示意图 **生活场景**电源插转换头、手机充电转换头、显示器转接头。 你可以创建一个适配器。 这是一个特殊的对象 能够转换对象接口 使其能与其他对象进行交互。 适配器模式通过封装对象将复杂的转换过程藏于幕后。 被封装的对象甚至察觉不到适配器的存在。 适配器不仅可以转换不同格式的数据 其还有助于采用不同接口的对象之间的合作。 它的运作方式如下 适配器实现与其中一个现有对象兼容的接口。现有对象可以使用该接口安全地调用适配器方法。适配器方法被调用后将以另一个对象兼容的格式和顺序将请求传递给该对象。 有时你甚至可以创建一个双向适配器来实现双向转换调用。 1.2 应用场景 封装有缺陷的接口设计统一多个类的接口设计替换依赖的外部系统兼容老版本接口适配不同格式的数据 1.3 适配器角色 Adaptee 是一组不兼容 ITarget 接口定义的接口。 ITarget 表示要转化成的接口定义。 Adapter/Adaptor 将 Adaptee 转化成一组符合 ITarget 接口定义的接口。 适配器有3中形式类适配器、对象适配器、接口适配器 1.4 类适配器 类适配器: 基于继承。 做法让Adaptor实现ITarget接口并且继承Adaptee这样Adaptor就具备ITarget和Adaptee的特性就可以将两者进行转化。 UML类图 // 类适配器: 基于继承// ITarget 表示要转化成的接口定义 public interface ITarget {void f1();void f2();void fc(); }// Adaptee 是一组不兼容 ITarget 接口定义的接口 public class Adaptee {public void fa() { //... }public void fb() { //... }public void fc() { //... } }// Adaptor 将 Adaptee 转化成一组符合 ITarget 接口定义的接口 public class Adaptor extends Adaptee implements ITarget {public void f1() {super.fa();}public void f2() {//...重新实现f2()...}// 这里fc()不需要实现直接继承自Adaptee这是跟对象适配器最大的不同点 }复制 1.5 对象适配器 对象适配器基于组合。 做法让Adaptor 实现ITarget 接口然后内部持有Adaptee实例然后在ITarget接口规定的方法内转换Adaptee。 URL类图 // 对象适配器基于组合// ITarget 表示要转化成的接口定义 public interface ITarget {void f1();void f2();void fc(); }// Adaptee 是一组不兼容 ITarget 接口定义的接口 public class Adaptee {public void fa() { //... }public void fb() { //... }public void fc() { //... } }// Adaptor 将 Adaptee 转化成一组符合 ITarget 接口定义的接口 public class Adaptor implements ITarget {private Adaptee adaptee;public Adaptor(Adaptee adaptee) {this.adaptee adaptee;}public void f1() {adaptee.fa(); //委托给Adaptee}public void f2() {//...重新实现f2()...}public void fc() {adaptee.fc();} }复制 1.5 接口适配器 使用接口适配器让我们只实现我们所需要的接口方法 public class CD { //这个类来自外部sdk我们无权修改它的代码//...public static void staticFunction1() { //... }public void uglyNamingFunction2() { //... }public void tooManyParamsFunction3(int paramA, int paramB, ...) { //... }public void lowPerformanceFunction4() { //... } }// 使用适配器模式进行重构 public class ITarget {void function1();void function2();void fucntion3(ParamsWrapperDefinition paramsWrapper);void function4();//... } // 注意适配器类的命名不一定非得末尾带Adaptor public class CDAdaptor extends CD implements ITarget {//...public void function1() {super.staticFunction1();}public void function2() {super.uglyNamingFucntion2();}public void function3(ParamsWrapperDefinition paramsWrapper) {super.tooManyParamsFunction3(paramsWrapper.getParamA(), ...);}public void function4() {//...reimplement it...} }1.6 实战 重构第三方登录自由适配场景 首先创建统一登陆结果ResultMsg类 Data public class ResultMsg {private int code;private String msg;private Object data;public ResultMsg(int code, String msg, Object data) {this.code code;this.msg msg;this.data data;} }假设老系统的的登录逻辑PasswordService public class PassportService {/*** 注册方法* param username* param password* return*/public ResultMsg regist(String username,String password){return new ResultMsg(200,注册成功,new Member());}/*** 登录的方法* param username* param password* return*/public ResultMsg login(String username,String password){return null;} }遵循开闭原则老代码我们不修改。开启代码重构之路创建Member类 Data public class Member {private String username;private String password;private String mid;private String info; }运行稳定的代码不改动。创建ITarget角色IPassportForThird接口。 public interface IPassportForThird {ResultMsg loginForQQ(String openId);ResultMsg loginForWechat(String openId);ResultMsg loginForToken(String token);ResultMsg loginForTelphone(String phone, String code); }创建适配器兼容Adaptor角色PassportForThirdAdapter类 public class PassportForThirdAdapter implements IPassportForThird {public ResultMsg loginForQQ(String openId) {return processLogin(openId, LoginForQQAdapter.class);}public ResultMsg loginForWechat(String openId) {return processLogin(openId, LoginForWechatAdapter.class);}public ResultMsg loginForToken(String token) {return processLogin(token, LoginForTokenAdapter.class);}public ResultMsg loginForTelphone(String phone, String code) {return processLogin(phone, LoginForTelAdapter.class);}private ResultMsg processLogin(String id,Class? extends ILoginAdapter clazz){try {ILoginAdapter adapter clazz.newInstance();if (adapter.support(adapter)){return adapter.login(id,adapter);}} catch (Exception e) {e.printStackTrace();}return null;} }根据不同登录方式创建不同登录Adaptor。首先创建LoginAdapter接口 public interface ILoginAdapter {boolean support(Object object);ResultMsg login(String id,Object adapter); }创建一个抽象类AbstraceAdapter继承PassportService原有功能同时实现ILoginAdapter接口然后分别实现不同的登录适配。 QQ登录 public class LoginForQQAdapter extends AbstraceAdapter{public boolean support(Object adapter) {return adapter instanceof LoginForQQAdapter;}public ResultMsg login(String id, Object adapter) {if(!support(adapter)){return null;}//accesseToken//timereturn super.loginForRegist(id,null);} }微信登录 public class LoginForWechatAdapter extends AbstraceAdapter{public boolean support(Object adapter) {return adapter instanceof LoginForWechatAdapter;}public ResultMsg login(String id, Object adapter) {return super.loginForRegist(id,null);} }手机登录 public class LoginForTelAdapter extends AbstraceAdapter{public boolean support(Object adapter) {return adapter instanceof LoginForTelAdapter;}public ResultMsg login(String id, Object adapter) {return super.loginForRegist(id,null);} }Token登录 public class LoginForTokenAdapter extends AbstraceAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForTokenAdapter;}public ResultMsg login(String id, Object adapter) {return super.loginForRegist(id,null);} }创建适配器PassportForThirdAdapter类实现目标接口IPassportForThird兼容。 public class PassportForThirdAdapter implements IPassportForThird {public ResultMsg loginForQQ(String openId) {return processLogin(openId, LoginForQQAdapter.class);}public ResultMsg loginForWechat(String openId) {return processLogin(openId, LoginForWechatAdapter.class);}public ResultMsg loginForToken(String token) {return processLogin(token, LoginForTokenAdapter.class);}public ResultMsg loginForTelphone(String phone, String code) {return processLogin(phone, LoginForTelAdapter.class);}private ResultMsg processLogin(String id,Class? extends ILoginAdapter clazz){try {ILoginAdapter adapter clazz.newInstance();if (adapter.support(adapter)){return adapter.login(id,adapter);}} catch (Exception e) {e.printStackTrace();}return null;} }客户端测试代码 public class Test {public static void main(String[] args) {IPassportForThird adapter new PassportForThirdAdapter();adapter.loginForQQ(sdfasdfasfasfas);} }类图 我们为每一个适配器加上了support()方法用来判断是否兼容参数是Object来源于接口。ILoginAdapter接口是为了代码规范。上面的代码综合了策略模式、简单工厂和适配器模式。 1.7 源码 Spring AOP中的AdvisorAdapter。有三个实现类MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter。 顶层接口AdvisorAdapter类 public interface AdvisorAdapter {boolean supportsAdvice(Advice var1);MethodInterceptor getInterceptor(Advisor var1); }MethodBeforeAdviceAdapter实现。其余两个不贴了。 class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {AfterReturningAdviceAdapter() {}public boolean supportsAdvice(Advice advice) {return advice instanceof AfterReturningAdvice;}public MethodInterceptor getInterceptor(Advisor advisor) {AfterReturningAdvice advice (AfterReturningAdvice)advisor.getAdvice();return new AfterReturningAdviceInterceptor(advice);} }Spring 根据不同的AOP配置确定使用相应的Advice。 下面看SpringMVC的HandlerAdapter类它也有多个子类。 类图 他的适配关键代码在DispatcherServlet的doDispatch()方法中我们看源码 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest request;HandlerExecutionChain mappedHandler null;boolean multipartRequestParsed false;WebAsyncManager asyncManager WebAsyncUtils.getAsyncManager(request);try {try {ModelAndView mv null;Object dispatchException null;try {processedRequest this.checkMultipart(request);multipartRequestParsed processedRequest ! request;mappedHandler this.getHandler(processedRequest);if (mappedHandler null) {this.noHandlerFound(processedRequest, response);return;}HandlerAdapter ha this.getHandlerAdapter(mappedHandler.getHandler());String method request.getMethod();boolean isGet GET.equals(method);if (isGet || HEAD.equals(method)) {long lastModified ha.getLastModified(request, mappedHandler.getHandler());if (this.logger.isDebugEnabled()) {this.logger.debug(Last-Modified value for [ getRequestUri(request) ] is: lastModified);}if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}mv ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}this.applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);} catch (Exception var20) {dispatchException var20;} catch (Throwable var21) {dispatchException new NestedServletException(Handler dispatch failed, var21);}this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);} catch (Exception var22) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);} catch (Throwable var23) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException(Handler processing failed, var23));}} finally {if (asyncManager.isConcurrentHandlingStarted()) {if (mappedHandler ! null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}} else if (multipartRequestParsed) {this.cleanupMultipart(processedRequest);}} }doDispatch方法调用了getHandlerAdaper方法 Nullable protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings ! null) {Iterator var2 this.handlerMappings.iterator();while(var2.hasNext()) {HandlerMapping hm (HandlerMapping)var2.next();if (this.logger.isTraceEnabled()) {this.logger.trace(Testing handler map [ hm ] in DispatcherServlet with name this.getServletName() );}HandlerExecutionChain handler hm.getHandler(request);if (handler ! null) {return handler;}}}return null; }getHandlerAdapter方法循环调用supports方法判断是否兼容循环迭代集合中的Adapter是在初始化时早就赋了值的。只有源码专题继续讲解。 1.8 适配器与装饰器的对比 两者都是包装模式 适配器装饰器形式适配器没有层级关系装饰器有层级关系。特殊的适配器定义适配器与被适配者没有必然联系通常通过继承或代理进行包装装饰器与被装饰者实现同一个接口目的是为了扩展后保留OOP关系关系has-a的关系is-a的关系功能注重兼容、转换注重覆盖、扩展设计后置考虑前置考虑 1.9 适配器模式的优缺点 优点 单一职责原则。你可以将接口或数据转换代码从程序主要业务逻辑中分离。开闭原则。只要客户端代码通过客户端接口与适配器进行交互 你就能在不修改现有客户端代码的情况下在程序中添加新类型的适配器。 缺点 代码整体复杂度增加 因为你需要新增一系列接口和类。 有时直接更改服务类使其与其他代码兼容会更简单。 1.10 总结 一般来说适配器模式可以看作一种“补偿模式”用来补救设计上的缺陷。应用这种模式算是“无奈之举”如果在设计初期我们就能协调规避接口不兼容的问题那这种模式就没有应用的机会了。那在实际的开发中什么情况下才会出现接口不兼容呢我总结下了下面这样 5 种场景 封装有缺陷的接口设计统一多个类的接口设计替换依赖的外部系统兼容老版本接口适配不同格式的数据 2 桥接模式 先复习代理模式。它在不改变原始类或者叫被代理类代码的情况下通过引入代理类来给原始类附加功能。代理模式在平时的开发经常被用到常用在业务系统中开发一些非功能性需求比如监控、统计、鉴权、限流、事务、幂等、日志。 今天学习桥接模式。桥接模式的代码实现非常简单但是理解起来稍微有点难度并且应用场景也比较局限所以相当于代理模式来说桥接模式在实际的项目中并没有那么常用你只需要简单了解见到能认识就可以并不是我们学习的重点。 2.1 原理解析 桥接模式也叫作桥梁模式英文是 Bridge Design Pattern。这个模式可以说是 23 种设计模式中最难理解的模式之一了。我查阅了比较多的书籍和资料之后发现对于这个模式有两种不同的理解方式。 示意图 当然这其中“最纯正”的理解方式当属 GoF 的《设计模式》一书中对桥接模式的定义。毕竟这 23 种经典的设计模式最初就是由这本书总结出来的。在 GoF 的《设计模式》一书中桥接模式是这么定义的“Decouple an abstraction from its implementation so that the two can vary independently。”翻译成中文就是“将抽象和实现解耦让它们可以独立变化。” 关于桥接模式很多书籍、资料中还有另外一种理解方式“一个类存在两个或多个独立变化的维度我们通过组合的方式让这两个或多个维度可以独立进行扩展。”通过组合关系来替代继承关系避免继承层次的指数级爆炸。这种理解方式非常类似于我们之前讲过的“组合优于继承”设计原则所以这里我就不多解释了。我们重点看下 GoF 的理解方式。 桥接模式通过组合关系来替代继承关系避免继承层次的指数级爆炸。 2.2 角色 类图 桥接模式有四个角色 抽象Abstraction)该类持有一个对实现角色的引用抽象角色中的方法需要实现角色。该类一般为抽象类。 修正抽象角色RefinedAbstractionAbstraction的具体实现对Abstraction方法进行完善与扩展。 抽象实现角色Implementor确定实现维度的基本操作提供给Abstraction使用。该类一般为接口或抽象类。 具体实现角色ConcreteImplementorImplementor的具体实现。 2.3 通用写法 创建抽象角色 // 抽象 public abstract class Abstraction {protected IImplementor mImplementor;public Abstraction(IImplementor implementor) {this.mImplementor implementor;}public void operation() {this.mImplementor.operationImpl();} }复制 修正抽象角色 // 修正抽象 public class RefinedAbstraction extends Abstraction {public RefinedAbstraction(IImplementor implementor) {super(implementor);}Overridepublic void operation() {super.operation();System.out.println(refined operation);} }抽象实现角色 // 抽象实现 public interface IImplementor {void operationImpl(); }具体实现角色 // 具体实现 public class ConcreteImplementorA implements IImplementor {public void operationImpl() {System.out.println(Im ConcreteImplementor A);} }测试代码 public class Test {public static void main(String[] args) {// 来一个实现化角色IImplementor imp new ConcreteImplementorA();// 来一个抽象化角色聚合实现Abstraction abs new RefinedAbstraction(imp);// 执行操作abs.operation();} }运行结果 Im ConcreteImplementor A refined operation复制 2.4 应用场景 拆分或重组一个具有多重功能的庞杂类 例如能与多个数据库服务器进行交互的类可以使用桥接模式。如果你希望在几个独立维度上扩展一个类可使用该模式。如果你需要在运行时切换不同实现方法可使用桥接模式。 2.5 业务场景中的运用 办公发送邮件、短信消息或者系统消息。紧急程度分为普通消息、紧急消息、特急消息。 使用继承的话情况复杂也不利于扩展。通过桥接来解决。 创建一个IMessage接口担任桥接角色 public interface IMessage {//发送消息的内容和接收人void send(String message,String toUser); }创建邮件消息实现EmailMessage类 public class EmailMessage implements IMessage {public void send(String message, String toUser) {System.out.println(使用邮件消息发送 message 给 toUser);} }创建手机消息实现SmsMessage类 public class SmsMessage implements IMessage {public void send(String message, String toUser) {System.out.println(使用短信消息发送 message 给 toUser);} }创建桥接抽象角色AbastractMessage类 public abstract class AbastractMessage {private IMessage message;public AbastractMessage(IMessage message) {this.message message;}void sendMessage(String message,String toUser){this.message.send(message,toUser);} }创建具体实现普通消息类NormalMessage public class NomalMessage extends AbastractMessage {public NomalMessage(IMessage message) {super(message);} }创建短信消息类SmsMessage public class SmsMessage implements IMessage {public void send(String message, String toUser) {System.out.println(使用短信消息发送 message 给 toUser);} }创建紧急消息UrgencyMessage类 public class UrgencyMessage extends AbastractMessage {public UrgencyMessage(IMessage message) {super(message);}void sendMessage(String message, String toUser){message 【加急】 message;super.sendMessage(message,toUser);}public Object watch(String messageId){return null;} }代码测试 public class Test {public static void main(String[] args) {IMessage message new SmsMessage();AbastractMessage abastractMessage new NomalMessage(message);abastractMessage.sendMessage(加班申请,王总);message new EmailMessage();abastractMessage new UrgencyMessage(message);abastractMessage.sendMessage(加班申请,王总);} }运行效果 使用短信消息发送加班申请给王总 使用邮件消息发送【加急】加班申请给王总2.6 源码 JDBC API其中Driver类就是桥接对象。使用Class.forName方法动态加载各个数据库厂商的Driver类。 以MySQL的实现为例 //1.加载驱动 Class.forName(com.mysql.jdbc.Driver); //反射机制加载驱动类 // 2.获取连接Connection //主机:端口号/数据库名 Connection conn DriverManager.getConnection(jdbc:mysql://localhost:3306/test, root, root); // 3.得到执行sql语句的对象Statement Statement stmt conn.createStatement(); // 4.执行sql语句并返回结果我们看一下Driver接口定义 public interface Driver {Connection connect(String url, java.util.Properties info)throws SQLException;boolean acceptsURL(String url) throws SQLException;DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info)throws SQLException;int getMajorVersion();int getMinorVersion();boolean jdbcCompliant();public Logger getParentLogger() throws SQLFeatureNotSupportedException; }Driver在JDBC中没有做任何实现具体的功能由各个厂商完成以MySQL的实现为例。 public class Driver extends NonRegisteringDriver implements java.sql.Driver {public Driver() throws SQLException {}static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException(Cant register driver!);}} }当我们执行Class.forName(“com.mysql.jdbc.Driver”)方法的时候就会执行com.mysql.jdbc.Drvier这个类的静态块中的代码。静态块中的代码只是调用了一下DriverManager的referisterDriver()方法然后将Driver对象注册到DriverMananger中。我们继续跟进到DriverManager这个类中来看相关代码 public class DriverManager {// List of registered JDBC driversprivate final static CopyOnWriteArrayListDriverInfo registeredDrivers new CopyOnWriteArrayList();/* Prevent the DriverManager class from being instantiated. */private DriverManager(){}/*** Load the initial JDBC drivers by checking the System property* jdbc.properties and then use the {code ServiceLoader} mechanism*/static {loadInitialDrivers();println(JDBC DriverManager initialized);}public static synchronized void registerDriver(java.sql.Driver driver)throws SQLException {registerDriver(driver, null);}public static synchronized void registerDriver(java.sql.Driver driver,DriverAction da)throws SQLException {/* Register the driver if it has not already been added to our list */if(driver ! null) {registeredDrivers.addIfAbsent(new DriverInfo(driver, da));} else {// This is for compatibility with the original DriverManagerthrow new NullPointerException();}println(registerDriver: driver);} }在注册之前将传过来的Driver对象封装成了一个DriverInfo对象。接下来继续执行客户端代码的第二部调用DriverManager的getConnection方法获取链接对象跟进源码 CallerSensitivepublic static Connection getConnection(String url,java.util.Properties info) throws SQLException {return (getConnection(url, info, Reflection.getCallerClass()));}CallerSensitivepublic static Connection getConnection(String url,String user, String password) throws SQLException {java.util.Properties info new java.util.Properties();if (user ! null) {info.put(user, user);}if (password ! null) {info.put(password, password);}return (getConnection(url, info, Reflection.getCallerClass()));}CallerSensitivepublic static Connection getConnection(String url)throws SQLException {java.util.Properties info new java.util.Properties();return (getConnection(url, info, Reflection.getCallerClass()));}// Worker method called by the public getConnection() methods.private static Connection getConnection(String url, java.util.Properties info, Class? caller) throws SQLException {/** When callerCl is null, we should check the applications* (which is invoking this class indirectly)* classloader, so that the JDBC driver class outside rt.jar* can be loaded from here.*/ClassLoader callerCL caller ! null ? caller.getClassLoader() : null;synchronized(DriverManager.class) {// synchronize loading of the correct classloader.if (callerCL null) {callerCL Thread.currentThread().getContextClassLoader();}}if(url null) {throw new SQLException(The url cannot be null, 08001);}println(DriverManager.getConnection(\ url \));// Walk through the loaded registeredDrivers attempting to make a connection.// Remember the first exception that gets raised so we can reraise it.SQLException reason null;for(DriverInfo aDriver : registeredDrivers) {// If the caller does not have permission to load the driver then// skip it.if(isDriverAllowed(aDriver.driver, callerCL)) {try {println( trying aDriver.driver.getClass().getName());Connection con aDriver.driver.connect(url, info);if (con ! null) {// Success!println(getConnection returning aDriver.driver.getClass().getName());return (con);}} catch (SQLException ex) {if (reason null) {reason ex;}}} else {println( skipping: aDriver.getClass().getName());}}// if we got here nobody could connect.if (reason ! null) {println(getConnection failed: reason);throw reason;}println(getConnection: no suitable driver found for url);throw new SQLException(No suitable driver found for url, 08001);}在getConnection()中又会调用各个厂商实现的Driver的connect()方法获得链接对象。这样的话就巧妙地避开了使用继承为不同数据库提供相同接口。JDBC API中DriverManager就是桥如下图所示 2.7 桥接模式优缺点 优点 你可以创建与平台无关的类和程序。客户端代码仅与高层抽象部分进行互动 不会接触到平台的详细信息。开闭原则。 你可以新增抽象部分和实现部分 且它们之间不会相互影响。单一职责原则。 抽象部分专注于处理高层逻辑 实现部分处理平台细节。 缺点 对高内聚的类使用该模式可能会让代码更加复杂。 2.8 代理、桥接、装饰器、适配器 4 种设计模式的区别 代理、桥接、装饰器、适配器这 4 种模式是比较常用的结构型设计模式。它们的代码结构非常相似。笼统来说它们都可以称为 Wrapper 模式也就是通过 Wrapper 类二次封装原始类。 **代理模式**代理模式在不改变原始类接口的条件下为原始类定义一个代理类主要目的是控制访问而非加强功能这是它跟装饰器模式最大的不同。 **桥接模式**桥接模式的目的是将接口部分和实现部分分离从而让它们可以较为容易、也相对独立地加以改变。 **装饰器模式**装饰者模式在不改变原始类接口的情况下对原始类功能进行增强并且支持多个装饰器的嵌套使用。 **适配器模式**适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口而代理模式、装饰器模式提供的都是跟原始类相同的接口。
http://www.hkea.cn/news/14434837/

相关文章:

  • wordpress炫酷站网站的推广平台
  • 影视传媒公司网站模板摄影设计网站
  • 四川省城乡和住房建设厅官方网站无锡公共工程建设中心网站
  • 做英语翻译赚钱的网站wordpress卖电子书
  • 网站开发与兼容模式中国贸易网登录
  • 做本地团购网站大连好的网站建设公司
  • 网站建设需求分析文档网站icp申请
  • 17网站一起做网店河北农业信息门户网站建设方案
  • .天津网站建设2014网站设计风格
  • 网站ip地址是什么做效果图的网站有哪些
  • 自己做网站和凡科的区别建筑专业名词网站
  • 包头哪里做网站怎么给网站做域名重定向
  • 网站访问频率站长
  • 免费建设com网站无锡华庄行业网站建设
  • 网站建设众包平台怎样登录建设互联网站
  • 合肥网站建设是什么意思只做画册的网站
  • 邹平建设网站网站开发 工期安排
  • 网站吸引客户东营刚刚发生
  • 名牌网站设计的图片直播网站开发接入视频
  • 静态网站优化网站开发怎么配合
  • 东风多利卡道路清障车做网站网站源码怎么打开
  • 网站默认首页怎么设置建设局怎么进
  • c语言开发网站教程网站建设销售招聘
  • 南通建设局网站网站建设初期怎么添加内容
  • 企业网站建设项目实践报告商城网站建设快速服务
  • 劳动人事争议仲裁网站建设名片在哪个网站做
  • 遵化网站建设衡阳网站优化公司
  • 夫妻网站开发网站开发 设计文档
  • 如何选网站建设公司网站建设新的技术方案
  • 网站设计师图片asp网站服务器架设