java设计模式之建造者模式 不念不忘少年蓝@ 2022-07-14 00:18 104阅读 0赞 建造者模式可以说是对工厂模式的扩展,工厂类提供了生产单个产品的功能,而建造者模式则可以将各种产品集中起来进行统一管理。工厂模式关注的是整个产品,建造者模式关注的是产品各组成部分的创建过程。 比如要创建一辆车,你只关心汽车本身(之后加以使用),就用工厂模式创建;若还关注该汽车的各部分是怎么造出来的(或者不同的工厂对产品的各部分的造法不同,就用Builder)。如StringBuilder对字符串的整合,append()、delete()、insert()改变数据。 **定义:** 建造者模式:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 **实用范围** 1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 2、当构造过程必须允许被构造的对象有不同表示时。 **角色** 在这样的设计模式中,有以下几个角色: 1、Builder( 抽象建造者):为创建一个产品对象的各个部件指定抽象接口。 2、ConcreteBuilder( 具体建造者):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。 3、Director( 导演者):构造一个使用Builder接口的对象,指导构建过程。 4、Product(产品):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。 导演者角色是与客户端打交道的角色。导演者将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但是却不为客户端所知。 一般来说,每有一个产品类,就有一个相应的具体建造者类。这些产品应当有一样数目的零件,而每有一个零件就相应地在所有的建造者角色里有一个建造方法。 # 角色Builder: # package com.deppon.tps.module.BuilderPatternTest; /** * 抽象建造者接口PersonBuilder(为创建一个产品对象的各个部件指定抽象接口) * @author 284724 */ public interface PersonBuilder { void builderHead(); void builderBody(); void builderFoot(); Person BuilderPerson(); } **角色ConcreteBuilder:** package com.deppon.tps.module.BuilderPatternTest; /** * 具体建造者类ManBuilder * @author 284724 * */ public class ManBuilder implements PersonBuilder{ Person person; public ManBuilder(){ person=new Man(); } public void builderHead(){ person.setHead("建造男人的头"); } public void builderBody(){ person.setBody("建造男人的身体"); } public void builderFoot(){ person.setFoot("建造男人的脚"); } public Person BuilderPerson(){ return person; } } **角色ConcreteBuilder:** package com.deppon.tps.module.BuilderPatternTest; /** * 具体建造者类WomanBuilder * @author 284724 * */ public class WomanBuilder implements PersonBuilder{ Person person; public WomanBuilder() { person=new Woman(); } public void builderHead(){ person.setHead("建造女人的头"); } public void builderBody(){ person.setBody("建造女人的身体"); } public void builderFoot(){ person.setFoot("建造女人的脚"); } public Person BuilderPerson(){ return person; } } **角色Director:** package com.deppon.tps.module.BuilderPatternTest; /** * 导演者类PersonDirector * @author 284724 * */ public class PersonDirector { public Person ConstructPerson(PersonBuilder pb){ pb.builderHead(); pb.builderBody(); pb.builderFoot(); return pb.BuilderPerson(); } } **角色Product:** package com.deppon.tps.module.BuilderPatternTest; public class Man extends Person{ public Man(){ System.out.println("开始建造男人"); } } package com.deppon.tps.module.BuilderPatternTest; public class Woman extends Person{ public Woman(){ System.out.println("开始建造女人"); } } package com.deppon.tps.module.BuilderPatternTest; public class Person { private String head; private String body; private String foot; public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getFoot() { return foot; } public void setFoot(String foot) { this.foot = foot; } } **测试:** package com.deppon.tps.module.BuilderPatternTest; public class Test { public static void main(String[] arg){ PersonDirector personDirector=new PersonDirector(); Person manPerson=personDirector.ConstructPerson(new ManBuilder()); Person womanPerson=personDirector.ConstructPerson(new WomanBuilder()); System.out.println(manPerson.getHead()); System.out.println(manPerson.getBody()); System.out.println(manPerson.getFoot()); System.out.println(womanPerson.getHead()); System.out.println(womanPerson.getBody()); System.out.println(womanPerson.getFoot()); } } # 使用场景 # 假设有一个电子杂志系统,定期地向用户的电子邮件信箱发送电子杂志。用户可以通过网页订阅电子杂志,也可以通过网页结束订阅。当客户开始订阅时,系统发送一个电子邮件表示欢迎,当客户结束订阅时,系统发送一个电子邮件表示欢送。本例子就是这个系统负责发送“欢迎”和“欢送”邮件的模块。注: **这个例子里面各个产品类均有一个共同的接口如下:** package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; import java.util.Date; public class AutoMessage { //收件人地址 private String to; //发件人地址 private String from; //主题 private String subject; //内容 private String body; //发送日期 private Date sendDate; public void send(){ System.out.println("收件人地址:"+to); System.out.println("发件人地址:"+from); System.out.println("主题:"+subject); System.out.println("内容:"+body); System.out.println("发送日期:"+sendDate); } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public Date getSendDate() { return sendDate; } public void setSendDate(Date sendDate) { this.sendDate = sendDate; } } 具体产品类WelcomeMessage package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class WelcomeMessage extends AutoMessage{ public WelcomeMessage(){ System.out.println("发送欢迎信息"); } } 具体产品类GoodbyeMessage package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class GoodbyeMessage extends AutoMessage{ public GoodbyeMessage(){ System.out.println("发送欢送信息啦!"); } } 抽象建造者类 package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; import java.util.Date; public abstract class Builder { protected AutoMessage msg; public abstract void builderSubject(); public abstract void builderBody(); public void builderTo(String to){ msg.setTo(to); } public void builderFrom(String from){ msg.setFrom(from); } public void builderSendDate(){ msg.setSendDate(new Date()); } public void sendMessage(){ msg.send(); } } 具体建造者WelcomeBuilder package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class WelcomeBuilder extends Builder{ public WelcomeBuilder(){ msg=new WelcomeMessage(); } public void builderSubject(){ msg.setSubject("欢迎标题"); } public void builderBody(){ msg.setBody("欢迎内容"); } } 具体建造者GoodbyeBuilder package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class GoodbyeBuilder extends Builder{ public GoodbyeBuilder(){ msg=new GoodbyeMessage(); } @Override public void builderSubject() { msg.setSubject("欢送标题"); } @Override public void builderBody() { msg.setBody("欢送内容"); } } 导演者Director package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class Director { Builder builder; public Director(Builder builder){ this.builder=builder; } public void construct(String toAdress,String fromAdress){ this.builder.builderTo(toAdress); this.builder.builderFrom(fromAdress); this.builder.builderSubject(); this.builder.builderBody(); this.builder.builderSendDate(); this.builder.sendMessage(); } } 客户端Client package com.deppon.tps.module.BuilderPatternTest.MessageBuilder; public class Test { public static void main(String[] arg){ Director director=new Director(new WelcomeBuilder()); director.construct("285457966@qq.com", "13966741558@qq.com"); director.construct("13966741558@qq.com", "285457966@qq.com"); } } 测试结果: 发送欢迎信息 收件人地址:285457966@qq.com 发件人地址:13966741558@qq.com 主题:欢迎标题 内容:欢迎内容 发送日期:Mon Nov 21 16:05:26 CST 2016 收件人地址:13966741558@qq.com 发件人地址:285457966@qq.com 主题:欢迎标题 内容:欢迎内容 发送日期:Mon Nov 21 16:05:27 CST 2016 **建造模式分成两个很重要的部分:** 1. 一个部分是Builder接口,这里是定义了如何构建各个部件,也就是知道每个部件功能如何实现,以及如何装配这些部件到产品中去; 2. 另外一个部分是Director,Director是知道如何组合来构建产品,也就是说Director负责整体的构建算法,而且通常是分步骤地来执行。 不管如何变化,**建造模式都存在这么两个部分,一个部分是部件构造和产品装配,另一个部分是整体构建的算法**。认识这点是很重要的,因为在建造模式中,强调的是固定整体构建的算法,而灵活扩展和切换部件的具体构造和产品装配的方式。 再直白点说,建造模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用。具体的构造实现可以很方便地扩展和切换,从而可以灵活地组合来构造出不同的产品对象。
还没有评论,来说两句吧...