23种设计模式的使用

23种设计模式的使用 文章目录创建模式工厂模式(factory)工厂模式最大的特点就是get方法吗?简单工厂模式(静态工厂模式)工厂方法模式抽象工厂模式原型模式(prototype)建造者模式(builder)单例模式(singleton)结构模式外观模式(facade)代理模式(proxy)适配器模式(adapter)组合模式(composite)装饰者模式(decorator 或 wrapper)装饰者模式和代理模式的区别桥接模式(bridge)享元模式(flyweight)行为模式模板模式(template)agentscope是模板模式吗?备忘录模式(memento)观察者模式(observer)产品类两个观察者调用职责链模式/责任链模式(Chain of Responsibility)责任链模式-传统方式责任链模式-优化方式命令模式(command)状态模式(state)策略模式(strategy)适配器模式和策略模式的区别?中介者模式(mediator)解释器模式(interpreter)访问者模式(visitor)设计模式实例根据代码判断出设计模式通用postClient的设计模式其他GoF是什么?设计模式有用么?必须有用啊。通过总结成设计模式可以通过一个名词来快速的描述出一段代码的结构例如说个单例模式大家一听就能想象出个大概。设计模式中有些技巧例如如何实现扩展性可维护性都是值得学习的。熟悉设计模式一定是高手么不一定但是高手一定熟悉涉及模式。23种设计模式是1995年提出的虽然大体概念不错但是这么多年过去了代码界早已天翻地覆无数回了。 所以可以参考不能太迷信它。很早就接触过设计模式当时也是懂了蓦然回首发现基本全忘了。还是方法不对光理解不行还要抓住要点才能记得牢。创建模式工厂模式(factory)创建和使用分开。开闭原则。解耦。隐藏new对象的逻辑。不使用工厂模式publicstaticvoidmain(String[]args){// 不用工厂方法BenzbenznewBenz();// 客户想要奔驰直接new一辆BmwbmwnewBmw();// 客户想要宝马直接new一辆}事实上客户不需要知道如何new一辆车只需要说我要需要什么车。工厂模式最大的特点就是get方法吗?当然不是最大的特点是隐藏创建过程。简单工厂模式(静态工厂模式)定义专门创建一个类来负责创建实例的工作被创建的实例通常具有相同的父类。mybatis-plus就是用的简单工厂模式。简单工厂代码publicclassSimpleFactory{publicCarcreateCar(Stringrequirement){if(requirement.equals(benz)){returnnewBenz();}elseif(requirement.equals(bmw)){returnnewBmw();}else{returnnewCar();}}}调用代码publicstaticvoidmain(String[]args){Stringrequirementbenz;CarcarnewSimpleFactory().createCar(requirement);}工厂方法模式话说我一直觉得工厂和抽象工厂差不多。 无非就是抽象工厂多实现了2个方法。Factory代码publicclassFactory{publicCarcreateCar();}BenzFactory代码publicclassBenzFactoryextendsFactory{OverridepublicCarcreateCar(){returnnewBenz();}}BmwFactory代码publicclassBmwFactoryextendsFactory{OverridepublicCarcreateCar(){returnnewBmw();}}抽象工厂模式分离了具体的类。原型模式(prototype)目的创建新对象比较复杂时利用clone方法简化对象的创建同时提高效率实现方式重写clone方法优点缺点深克隆时代码可能比较复杂需要为每个类配置一个clone方法如果要调整需要修改源码应用场景创建新对象比较复杂时利用clone方法简化对象的创建同时提高效率不用初始化对象可以动态的克隆当前对象以及他的状态原始对象发生改变克隆对象的也会发生相应的变化无需修改代码publicObjectclone(){Objectclonenull;try{clonesuper.clone();}catch(CloneNotSupportedExceptione){e.printStackTrace();}returnclone;}建造者模式(builder)隐藏建造的细节。一个builder实现类用来封装部件的逻辑。一个directory(经理导演)/manager来组合要装配哪些部件。经过这2层关系可以具有高扩展性。mybatis-plus的wrapper就是建造者模式。agentscope中也用到了建造者模式。要建造的对象类Person和build类。publicclassPerson{Stringname;intage;doubleweight;intscore;Locationloc;privatePerson(){}publicstaticclassPersonBuilder{PersonpnewPerson();publicPersonBuilderbasicInfo(intid,Stringname,intage){p.idid;p.namename;p.ageage;returnthis;}publicPersonBuilderweight(doubleweight){p.weightweight;returnthis;}publicPersonBuilderscore(intscore){p.scorescore;returnthis;}publicPersonBuilderloc(Stringstreet,StringroomNo){p.locnewLocation(street,roomNo);returnthis;}publicPersonbuild(){returnp;}}}调用代码PersonpnewPerson.PersonBuilder().basicInfo(1,zhangsan,18)// .score(20).weight(200)// .loc(bj,23).build();简言之就是在builder里面有要建造的对象person通过方法设置person的属性值返回的还是builder对象这样就可以继续builder最后再通过build()方法返回最终创建的对象。单例模式(singleton)目的一个类只有一个实例免去频繁创建和销毁的过程。实现方式构造函数私有化保证在外部无法new对象提供一个static方法获取当前实例不同方案实现不同优点缺点一般没有接口扩展困难。单例对象如果持有Context那么很容易引发内存泄漏此时需要注意传递给单例对象的Context最好是Application Context。应用场景对象频繁创建销毁或者对象创建比较消耗资源全局访问点共享资源访问如controller就是用的单例饿汉式publicclassSingleton{privatestaticSingletonsingletonnewSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnsingleton;}}懒汉式publicclassSingleton{privatestaticSingletonsingleton;privateSingleton(){}publicstaticSingletongetInstance(){if(nullsingleton){singletonnewSingleton();}returnsingleton;}}结构模式外观模式(facade)代理模式(proxy)适配器模式(adapter)组合模式(composite)装饰者模式(decorator 或 wrapper)wrapper模式的实现过程wrapper类实现该接口wrapper类引如该接口实例写入新方法覆盖接口方法新方法可以添加再接口方法的前后装饰者模式和代理模式的区别到decorator模式的时候我一看这不就是代理模式么?实现上确实很类似但是也有些区别。对装饰器模式来说装饰者decorator和被装饰者decoratee都实现同一个 接口。对代理模式来说代理类proxy class和真实处理的类real class都实现同一个接口。他们之间的边界确实比较模糊两者都是对类的方法进行扩展具体区别如下1、装饰器模式强调的是增强自身在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你只不过能力更强了而已代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责记录日志、设置缓存。代理模式是为了实现对象的控制因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。2、装饰模式是以对客户端透明的方式扩展对象的功能是继承方案的一个替代方案代理模式则是给一个对象提供一个代理对象并由代理对象来控制对原有对象的引用3、装饰模式是为装饰的对象增强功能而代理模式对代理的对象施加控制但不对对象本身的功能进行增强后来又进行了一种区分如果注入的是个具体类那么一般为装饰器模式。如果注入的是个接口那么一般为为代理模式。java代理模式–和装饰器模式有点像的模式 # 这篇博客写的比较明白桥接模式(bridge)感觉这个模式就是如果可能有多个组合一个采用继承。一个采用set类作为属性的方式。实现组合功能。享元模式(flyweight)行为模式模板模式(template)jdbcTemplatehttpServlet就是用的模板模式。agentscope是模板模式吗?好问题看上去像但是不是。1、结构像模板方法2、但语义上不是模板方法模式3、更像“模板方法 策略模式 组件容器”的混合体总结JdbcTemplate 是模板方法模式的现代回调版AgentScope是受模板方法启发但以组件化和策略替换为核心的运行框架。备忘录模式(memento)观察者模式(observer)这个内容有点多拆出来见其他文章。event、listener就是典型的观察者模式。在看mq的RabbitListener注解时想它的机制突然发现可能和观察者模式有关。要点java有现成的api主要就两个。第一。我们必须extendsJava.util.Observer才能真正使用它:1.提供Add/Delete observer的方法;2.提供通知(notisfy) 所有observer的方法;第二。Observable类。在每个属性的变动时都设置变动并通知到所有观察者。产品类//产品类 可供Jsp直接使用UseBean调用 该类主要执行产品数据库插入 更新publicclassproductextendsObservable{privateStringname;privatefloatprice;publicStringgetName(){returnname;}publicvoidsetName(){this.namename;//设置变化点setChanged();notifyObservers(name);}publicfloatgetPrice(){returnprice;}publicvoidsetPrice(){this.priceprice;//设置变化点setChanged();notifyObservers(newFloat(price));}//以下可以是数据库更新 插入命令.publicvoidsaveToDb(){.....................}两个观察者观察者1//观察者NameObserver主要用来对产品名称(name)进行观察的publicclassNameObserverimplementsObserver{privateStringnamenull;publicvoidupdate(Observableobj,Objectarg){if(arginstanceofString){name(String)arg;//产品名称改变值在name中System.out.println(NameObserver :name changet to name);}}}观察者2//观察者PriceObserver主要用来对产品价格(price)进行观察的publicclassPriceObserverimplementsObserver{privatefloatprice0;publicvoidupdate(Observableobj,Objectarg){if(arginstanceofFloat){price((Float)arg).floatValue();System.out.println(PriceObserver :price changet to price);}}}调用publicclassTest{publicstaticvoidmain(Stringargs[]){ProductproductnewProduct();NameObservernameobsnewNameObserver();PriceObserverpriceobsnewPriceObserver();//加入观察者product.addObserver(nameobs);product.addObserver(priceobs);product.setName(橘子红了);product.setPrice(9.22f);}}你会在发现下面信息::NameObserver :name changet to 橘子红了PriceObserver :price changet to 9.22这说明观察者在行动了.!!职责链模式/责任链模式(Chain of Responsibility)责任链模式主要用于处理那些需要经过多个处理步骤或处理者才能完成的请求。其主要应用场景包括1、过滤器模式例如在Java Web应用中过滤器链用于对HTTP请求和响应进行处理。每个过滤器负责处理特定的任务然后将请求传递给下一个过滤器。这种场景下责任链模式可以有效地解耦每个过滤器的处理逻辑。2、事件处理模式在图形用户界面编程中事件处理通常采用责任链模式。例如在一个按钮上可能有多个监听器如点击、鼠标移动等每个监听器负责处理一种特定的事件。当事件发生时会沿着监听器链进行传递直到有监听器处理该事件为止。3、工作流引擎在企业级应用中工作流引擎通常使用责任链模式来处理复杂的业务流程。每个处理节点负责处理流程中的特定步骤然后将工作项传递给下一个处理节点。4、权限设计在权限设计中可以使用责任链模式来实现权限验证。例如一个用户可能需要经过多个角色的权限验证每个角色负责验证一部分权限。这样既可以实现权限验证的逻辑分离又可以提高系统的灵活性和扩展性。例如其中的一个好处解耦对比下就明白了。责任链模式-传统方式最简单的例子就是if来区分代码是真的丑而且如果有变化改起来一团乱。if(.equal(已下单)){}elseif(.equal(已发货)){}elseif(.equal(已签收)){}责任链模式-优化方式抽象类代码publicabstractclassHandler{protectedHandlernextHandler;publicvoidsetNextHandler(HandlernextHandler){this.nextHandlernextHandler;}publicabstractvoidhandleRequest(Stringrequest);}实现类ApublicclassConcreteHandlerAextendsHandler{OverridepublicvoidhandleRequest(Stringrequest){if(request.equals(A)){System.out.println(ConcreteHandlerA处理了请求request);}elseif(nextHandler!null){nextHandler.handleRequest(request);}else{System.out.println(没有处理器可以处理该请求request);}}}实现类BpublicclassConcreteHandlerBextendsHandler{OverridepublicvoidhandleRequest(Stringrequest){if(request.equals(B)){System.out.println(ConcreteHandlerB处理了请求request);}elseif(nextHandler!null){nextHandler.handleRequest(request);}else{System.out.println(没有处理器可以处理该请求request);}}}调用代码publicclassClient{publicstaticvoidmain(String[]args){HandlerhandlerAnewConcreteHandlerA();HandlerhandlerBnewConcreteHandlerB();handlerA.setNextHandler(handlerB);handlerA.handleRequest(A);// 输出ConcreteHandlerA处理了请求AhandlerA.handleRequest(B);// 输出ConcreteHandlerB处理了请求BhandlerA.handleRequest(C);// 输出没有处理器可以处理该请求C}}命令模式(command)状态模式(state)策略模式(strategy)spring中的导入导出就是用的策略工厂模式。适配器模式和策略模式的区别?策略模式和适配器模式都是一个接口多个实现类所以看上去比较像。但是是不同的核心区别1、是平级替换还是跨界翻译策略模式是平级替换如导入导出不同的功能适配器模式是跨界翻译入参五花八门httpRequestrequestBody都要适配2、是主动选择还是被动兜底策略模式是主动选择例如导入用户模块适配器模式是被动兜底之前就有各式各样的方法必须适配中介者模式(mediator)解释器模式(interpreter)访问者模式(visitor)①装饰器模式特点:1 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。2 装饰对象包含一个真实对象的引用reference3 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。4 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中通常是通过继承来实现对给定类的功能扩展。设计模式实例根据代码判断出设计模式有这个想法是因为看到一段代码突然想这是用的什么设计模式呢?结果居然真的搞不清楚也不知道学的什么玩意。通用postClient的设计模式场景公司接口需要批量化部署每家公司账号密码不同部署的机器也不同但是调用的方法库相同方法库分为不同大模块每个模块有多个接口。经过设计觉得这个方式不错。PostClient类publicPostClient(StringserverUrl,Stringkey,Stringsecret){this.keykey;this.secretsecret;this.serverUrlserverUrl;}// 功能组 有几个大模块就添加多少功能组publicUserGroupuser(){returnnewUserGroup(this);}功能组抽象类FunctionGrouppublicabstractclassFunctionGroup{protectedPostClientclient;publicFunctionGroup(PostClientclient){this.clientclient;}}用户功能组类publicclassUserGroupextendsFunctionGroup{publicUserGroup(IBWClientclient){super(client);}publicUserQueryResponsequery(UserQueryRequestrequest,Stringtoken,StringrequestId){return(UserQueryResponse)this.client.execute(request,token,requestId,UserQueryResponse.class);}}最终调用PostClientclientnewPostClient(url,key,secret);UserQueryResponseresponseclient.user().queryUser(request,token);这样无论后续有多少功能都很好扩展进来而且从外部的调用代码很统一很容易掌握。那么运用了哪些设计模式呢?1、构造器模式(有这个模式吗?别瞎创造)。一般来说构造器模式可以通过方法来返回对象最后以build()结尾。这里虽然没有以build结尾但是相当于build的效果。应该是用了build模式。其他GoF是什么?GoF(gang of four)(四人帮)这4个人总结出23种设计模式并出了一本书对设计模式的发展影响深远。