建造(Builder)模式 【创建模式第六篇】
建造(Builder)模式
建造模式是对象的创建模式。
产品的内部表象:一个产品常有不同的组成成分作为产品的零件,这些零件有可能是对象,也有可能不是对象它们通常叫做产品的内部表象
角色:
1、抽象建造者角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,有多少个零件就有多少个建造方法
2、具体建造者角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序的调用下创建产品的实例。
这个角色完成的人物包括:
1)实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。
2)在建造过程完成后,提供产品的实例
3、导演者角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者角色并没有产品类的具体知识,真正拥有产品类
具体知识的是具体建造者角色。
4、产品角色:产品便是建造中的复杂对象。一般来说,一个系统会有多余一个的产品类,而且这些产品类并不一定有共同的接口
而完全可以是不想关联的。
(导演者角色是与客户端打交道的角色)
一般类说:没有一个产品类,就有一个相应的具体建造者类。
public class Driector{private Builder builder;//产品构造方法,负责调用各个零件建造方法public void construct(){builder = new ConcreteBuilder();builder.buildPart1();builder.buildPart2();builder.retrieveResult();//retrieve检索}}//抽象建造者public abstract class Builder{//产品零件建造方法public abstract void buildPart1();public abstract void buildPart2();//产品返回方法public abstract Product retrieveResult();}//具体建造者public class ConcreteBuilder extends Builder{private Product product = new Product();//产品返回方法public Product retrieveResult(){return product;}//产品零件建造方法public void buildPart1(){//build the first part of the product}public void buildPart2(){//build the second part of the product}}//产品类public class Product{//...................}//如果省略了导演者角色//客户端代码public class Client{private static Builder builder;public static void main(String args[]){//创建建造者对象builder = new Builder();//拥有建造者对象的产品构造方法builder.construct();//调用建造者对象的产品返还方法以取得产品Product product = builder.retrieveResult();} }模板方法模式:准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式如果系统的要求发生变化,要求有不同的零件生成逻辑时,那么设计师有两种选择:1、一是修改这个退化的建造模式,将它改回成为完全的建造模式,这当然就要涉及到代码的修改了;2、二是不修改代码,而是将Builder类扩展到不同的子类,在这些子类里面置换掉需要改变的建造方法如果一个产品对象有着固定的几个零件,而且永远只有这几个零件。此时将产品类于建造类合并*在很多情况下,建造模式实际上是将一个对象的性质建造过程外部化到独立的建造者对象中,并通过一个导演者角色对这些外部化的性质赋值过程进行协调。一个简单的发送电子邮件的客户端import java.util.*;import java.io.*;import javax.mail.*;import javax.mail.internet.*;import javax.activation.*;public class MailSender{private static MineMessage message;public static void main(String args[]){//你的SMTP服务器地址String smtpHost = "smtp.mycompany.com";//发送者的地址String from = "joff.yan@mycompany.com";//收信者地址String to = "ni.hao@youcompany.com";Properties props = new Properties();props.put("mail.smtp.host", smtpHost);Session session = Session.getDefaultInstance(props,null);try{InternetAddress[] address = new InternetAddress(to);//创建Message对象message = new MineMessage(session);//建造发件人位元址零件message.setFrom(new InternetAddress(from));//建造收件人位元址零件message.setRecipients(Message.RecipientType.TO,address);//建造主题零件messgae.setSubject("Hello from Jeff");//建造发送时间零件message.setSentDate(new Date());//建造内部零件message.setText("Hello,\nHow are things going?");//发送邮件,相当于产品返回方法Transport.send(message);System.out.println("email has been sent.");}catch(Exception e){System.out.println(e);}}}/////////////////////////////////////////////////////////////////////////////导演类public class Director{Builder builder;public Director(Builder builder){this.builder = builder;}//产品构造方法,负责调用各零件建造方法public void construct(String toAddress, String fromAddress){this.builder.buildSubject();this.builder.buildBody();this.builder.buildTo(toAddress);this.builder.buildFrom(fromAddress);this.builder.buildSendDate();this.builder.sendMessage();}}//抽象建造者类import java.util.Date;public abstract class Builder{protected AutoMessage msg;public Builder(){}//主题零件的建造方法public abstract void buildSubject();//内容零件的建造方法public abstract void buildBody();//发件人零件的建造方法public void buildFrom(String from){msg.setFrom(from);}//收件人零件的建造方法public void buildTo(String to){System.out.println(to);msg.setTo(to);}//发送时间零件的建造方法public void buildSendDate(){msg.setSendDate(new Date());}//邮件产品完成后,用此方法发送邮件//此方法相当于产品返回方法public void sendMessage(){msg.send();}}//具体建造类public class WelcomeBuilder extends Builder{private static final String subject = "Welcome to philharmony news group";public WelcomeBuilder(){msg = new WelcomeMessage();}//主题零件的建造方法public void buildSubject(){msg.setSubject(subject);}public void buildBody(){String body = "Congratulations for making the choice!";msg.setBody(body);}//邮件产品建造完成后,发送邮件//此方法相当于产品返还方法public void sendMessage(){msg.send();}}