当前位置: 首页 > 科技观察

设计模式系列—建造者模式

时间:2023-03-19 17:16:07 科技观察

前言23设计模式速记单例模式工厂方法模式抽象工厂模式23设计模式快速记忆请看上文第一篇。这篇文章,我们一起来了解一下建造者模式。模式定义将复杂对象的创建与其表示分开,允许相同的构建过程创建不同的表示。用户只需指定复杂对象的类型和内容;建造者模式负责按顺序创建复杂对象(隐藏内部构造过程和细节),解决降低创建复杂对象的复杂度,隔离创建对象的构造过程&表示:方便用户创建复杂对象(无需知道实现过程)Codereusability&encapsulation(对象构造过程和细节的封装&复用性)模式组合导演(Director)直接与客户(Client)进行需求沟通;沟通后,指挥将客户的产品创建需求分解为每个组件(Builder)的构建请求;将每个组件的构建请求分配给特定的构建器(ConcreteBuilder);每个特定的构建器负责产品组件。建造;最终构建成具体的产品(Product)。示例描述示例概述背景小张想去中关村购买一台组装好的台式主机。过程中,关村老板(Diretor)和小张(Client)互相沟通(买来玩游戏?学习?看电影?)了解需求后,电脑城老板将小张需要的主机分成建设需求(CPU,主板...)每个组件(Builder),并指示安装程序(ConcreteBuilder)构建组件;)使用步骤第一步:定义一个具体的产品类别(Product):计算机类Computer{//计算机组件的集合privateListparts=newArrayList();//用于将组件组装成计算机publicvoidAdd(Stringpart){parts.add(part);}publicvoidShow(){for(inti=0;i{publicstaticvoidmain(String[]args){//Step5:Clientcall-小张去电脑城买电脑找老板买电脑//逛了半天,终于找到合适的电脑店//找到店主和安装商Directordirector=newDirector();Builderbuilder=newConcreteBuilder();//沟通后要求,老板让安装师傅安装电脑director.Construct(builder);//安装完成后,组装机移动到组装好的电脑上组件主板安装好,硬盘安装完毕,电脑组装完毕。请检查并接受优点。良好的封装性:构建者对客户端屏蔽了产品内部组成的细节,客户端无需关心每个具体的产品是如何按照开闭原则实现的。易于控制细节风险:由于构建者相互独立,构建过程可以逐步细化,不影响其他模块。每个具体的建造者都是相对独立的,与其他具体的建造者无关。因此,很容易替换特定构建器或添加新的特定构建器。用户可以通过使用不同的特定构建器获得不同的产品对象。缺点建造者模式打造的产品一般有较多的共同点,其组件也大同小异;如果产品差别很大,就不适合使用builder模式,所以它的使用范围是有限的。如果产品内部变化比较复杂,可能会导致需要定义很多具体的构建器类来实现这种变化,导致系统非常庞大。应用场景要求生成的对象具有复杂的内部结构。生成对象的内部属性是相互依赖的,并与不可变对象结合使用。与工厂方法模式的区别。建造者模式的主要作用是基本方法的调用顺序安排。基本方法已经实现,我们可以理解为零件的组装,不同的顺序生产出来的对象也不同;而工厂方法的重点是创建,部件的创建是它的主要职责,它不关心装配的顺序。源码中的应用#jdkjava.lang.StringBuilder#Spring源码org.springframework.web.servlet.mvc.method.RequestMappingInfoorg.springframework.beans.factory.support.BeanDefinitionBuilder...StringBuilder源码分析jdk中的StringBuilder类的实现,采用了建造者模式的思想。具体分析如下:StringBuilder类继承自AbstractStringBuilder,AbstractStringBuilder实现了Appendable接口。AbstractStringBuilder虽然是一个抽象类,但是它实现了Appendable接口中的各个append()方法,所以这里的Appendable接口是一个抽象的构建器,AbstractStringBuilder是一个构建器,但是不能实例化。对于StringBuilder类,它不仅充当指挥官,还充当具体的建造者。构造方法的具体实现由继承AbstractStringBuilder的AbstractStringBuilder完成。Appendable接口publicinterfaceAppendable{Appendableappend(CharSequencecsq)throwsIOException;Appendableappend(CharSequencecsq,intstart,intend)throwsIOException;Appendableappend(charc)throwsIOException;}AbstractStringBuilder类abstractclassAbstractStringBuilderimplementsAppendable,CharSequence{char[]value;//Thevalueisusedforcharacterstorage.intcount;//Thecountisthenumberofcharactersused.AbstractStringBuilder(){}AbstractStringBuilder(intcapacity){value=newchar[容量];}publicAbstractStringBuilderappend(Stringstr){if(str==null)returnappendNull();intlen=str.length();ensureCapacityInternal(count+len);str.getChars(0,len,value,count);count+=len;returnthis;}privateAbstractStringBuilderappendNull(){intc=count;ensureCapacityInternal(c+4);finalchar[]value=this.value;value[c++]='n';value[c++]='u';value[c++]='l';value[c++]='l';count=c;returnthis;}privatevoidensureCapacityInternal(intminimumCapacity){//溢出意识codeif(minimumCapacity-value.length>0){value=Arrays.copyOf(value,newCapacity(minimumCapacity));}}publicvoidgetChars(intsrcBegin,intsrcEnd,chardst[],intdstBegin){if(srcBegin<0){thrownewStringIndexOutOfBoundsException(srcBegin);}if(srcEnd>value.length){thrownewStringIndexOutOfBoundsException(srcEnd);}if(srcBegin>srcEnd){thrownewStringIndexOutOfBoundsException(srcEnd-sr??cBegin);}System.arraycopy(value,srcBegin,dst,dstBegin,srcEnd-sr??cBegin);}//这个省略........在Github上:https://github.com/Niuh-Study/niuh-designpatterns.git