`

读《研磨设计模式》-代码笔记-生成器模式-Builder

阅读更多
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/




/**
 * 生成器模式的意图在于将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示(GoF)
 * 个人理解:
 * 构建一个复杂的对象,对于创建者(Builder)来说,一是要有数据来源(rawData),二是要返回构建好的对象(product)
 * 那么AbstractBuilder就自然持有了rawData和product对象
 * 然后将创建过程分成相对不变的几个步骤,这几个步骤交由子类去实现,那就实现了不同的Builder能“创建不同的表示”
 * 另外,定义一个Director,将Builder创建产品的几个步骤封装到一个方法里,向外提供统一的接口而不暴露细节
 * 
 * 书上考虑了一个数据导出到文件的问题。假设要生成的HTML和XML文件都只包含header和body
 */

abstract class AbstractBuilder {
	
	//构造产品的原始数据。也可以写成方法参数传递:buildHeader(String rawData);buildBody(String rawData);
	protected String rawData;
	
	protected FileProduct product;

	public abstract void buildHeader();

	public abstract void buildBody();

	public FileProduct getProduct() {
		return product;
	}
	
}

class HTMLBuilder extends AbstractBuilder {
	
	public HTMLBuilder(String rawData) {
		this.rawData = rawData;
		this.product = new FileProduct();
	}
	
	@Override
	public void buildHeader() {
		String[] rawDatas = rawData.split(",");
		product.setHeader("<html:header>" + rawDatas[0] + "</html:header>");
	}

	@Override
	public void buildBody() {
		String[] rawDatas = rawData.split(",");
		product.setBody("<html:body>" + rawDatas[1] + "</html:body>");
	}

}

class XMLBuilder extends AbstractBuilder {
	
	public XMLBuilder(String rawData) {
		this.rawData = rawData;
		this.product = new FileProduct();
	}
	
	@Override
	public void buildHeader() {
		String[] rawDatas = rawData.split(",");
		product.setHeader("<xml:header>" + rawDatas[0] + "</xml:header>");
	}

	@Override
	public void buildBody() {
		String[] rawDatas = rawData.split(",");
		product.setBody("<xml:body>" + rawDatas[1] + "</xml:body>");
	}

}


class FileProduct {

    private String header;
    private String body;

    public String getHeader() {
        return header;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
    
    public String toString() {
        return  header + "\n" + body;
    }

}


class Director {
	
	private AbstractBuilder builder;

	public Director(AbstractBuilder builder) {
		this.builder = builder;
	}
	
	public void build() {
		builder.buildHeader();
		builder.buildBody();
	}
	
}


public class BuilderPattern {

	public static void main(String[] args) {
		String rawData = "xx,yy";
		
		AbstractBuilder xmlBuilder = new XMLBuilder(rawData);
		Director director = new Director(xmlBuilder);
		director.build();
		System.out.println(xmlBuilder.getProduct());
		
		AbstractBuilder htmlBuilder = new HTMLBuilder(rawData);
		Director director2 = new Director(htmlBuilder);
		director2.build();
		System.out.println(htmlBuilder.getProduct());
		
		//测试:用Builder模式创建对象
		MassiveObject data = new MassiveObject.Builder("001").name("Tom").position("CEO").build();
		System.out.println(data);
	}

}



/**
 * 创建有约束的复杂对象。可以在两个地方加上约束:
 * 1、在InsuranceContract的构造函数时加约束
 * 2、在Builder的setter里面加约束
 */
class InsuranceContract {
    
    private String id;
    private String name;
    private String position;
    
    /*
     * 访问类别是default,不支持包外的其他类直接利用构造函数来创建InsuranceContract,
     * 但也带来一个问题是,同包的其他类可能会直接调用构造函数来创建InsuranceContract
     * 因此,较好的办法是像Effective Java里面建议的那样,把Builder做成inner class
     */
    //1.可以这里加约束
    InsuranceContract(ConcreteBuilder builder) {
        this.id = builder.getId();
        this.name = builder.getName();
        this.position = builder.getPosition();
    }
    
    public String toString() {
        return "id = " + id + ",name = " + name + ",position = " + position;
    }
    
    public void otherOperation() {
        
    }
    
}


class ConcreteBuilder {
    
    private String id;
    private String name;
    private String position;
    
    public InsuranceContract build() {
        return new InsuranceContract(this);
    }
    
    //假设id是必填数据,其他为选填数据
    public ConcreteBuilder(String id) {
        this.id = id;
    }
    
    //将ConcreteBuilder返回
    public ConcreteBuilder setName(String name) {
      //2.可以这里加约束
        this.name = name;
        return this;
    }

    public ConcreteBuilder setPosition(String position) {
        this.position = position;
        return this;
    }
    
    public String getPosition() {
        return position;
    }

    public String getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
}



/**
 * Effective Java里面建议:
 * 在生成一个复杂对象(field很多,造成构造函数的参数列表很长且顺序易出错)时,考虑用Builder模式
 */
class MassiveObject {
	private String id;
	private String name;
	private String position;

	private MassiveObject(Builder builder) {
		this.id = builder.id;
		this.name = builder.name;
		this.position = builder.position;
	}

	public String toString() {
		return "id=" + id + ",name=" + name + ",position=" + position;
	}
	
	public static class Builder {
		private String id;
		private String name;
		private String position;

		public Builder(String id) {
			this.id = id;
		}

		public Builder name(String name) {
			this.name = name;
			return this;
		}
		
		public Builder position(String position) {
			this.position = position;
			return this;
		}

		public MassiveObject build() {
			return new MassiveObject(this);
		}
	}
}



分享到:
评论

相关推荐

    研磨设计模式-配套源代码

    研磨设计模式-配套源代码研磨设计模式-配套源代码

    研磨设计模式-配套源代码.rar

    研磨设计模式-配套源代码.rar

    研磨设计模式-配套源代码.7z

    研磨设计模式-配套源代码.7z

    研磨设计模式-配套源代码 UTF-8格式

    研磨设计模式第二版-配套源代码 UTF-8格式 研磨设计模式第二版-配套源代码 UTF-8格式

    研磨设计模式-陈臣.epub

    “1.1 设计模式是什么 1.1.1 什么是模式 从字面上理解,模,就是模型、模板的意思;式,就是方式、方法的意思。综合起来,所谓模式就是:可以作为模型或模板的方式或方法。... “研磨设计模式”。 iBooks.

    研磨设计模式-陈臣.王斌.扫描高清版PDF

    设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;...

    研磨设计模式-陈臣pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式书-配套源代码(全)

    1:本源代码是《研磨设计模式》一书的配套源代码 2:每个模式的示例源代码放在一个单独的文件夹下,以该模式的英文名称命名 3:每个模式下分成多个example,按照书的示例顺序分别命名为example1、example2.........

    研磨设计模式-陈臣.mobi kindle版

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part2

    第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) ...

    研磨设计模式-part4

    第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) ...

    研磨设计模式-part3

    第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) ...

    研磨设计模式--chjavach的博客文章

    单例模式、工厂方法模式、策略模式、命令模式和桥接模式。

    研磨设计模式 源代码

    研磨设计模式 源代码 书上面的例子都在里面

    研磨设计模式源码

    研磨设计模式的配套源码,请下载,不要想了,解压后,直接放到eclipse下面即可运行!

    研磨设计模式全部源代码

    研磨设计模式全部源代码,个人收集,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!

    研磨设计模式(完整带书签).part2.pdf

    第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) ...

    研磨设计模式带书签完整版228M.7z.001

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式 完美书签 完整(一)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式带书签完整版228M.7z.002

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

Global site tag (gtag.js) - Google Analytics