`

读《研磨设计模式》-代码笔记-生成器模式-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);
		}
	}
}



分享到:
评论

相关推荐

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

    这份压缩包可能包括了多种常见设计模式的实现,如单例模式、工厂模式、观察者模式、装饰器模式等,通过源代码的形式帮助开发者更好地理解和应用这些模式。 1. **单例模式**:确保一个类只有一个实例,并提供一个...

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

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,其配套源代码包含了许多经典设计模式的实际应用示例。这些源代码可以帮助读者更直观地理解设计模式的原理和使用方法,进一步提升软件开发能力。 设计模式是软件...

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

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,配套源代码是作者为了帮助读者更好地理解和应用书中介绍的设计模式而提供的实践示例。设计模式是软件开发中经过实践检验的、解决常见问题的模板,它为软件设计...

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

    《研磨设计模式》是一本深入探讨软件设计原则与实践的经典书籍,其配套源代码提供了丰富的实例,帮助读者更好地理解和应用各种设计模式。这个UTF-8格式的压缩包包含了书中介绍的各种设计模式的实现,是学习和研究...

    研磨设计模式-陈臣.epub

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

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

    研磨设计模式的过程是持续学习和实践的过程,chjavach的博客文章提供了深入探讨这些模式的宝贵资源,值得我们仔细阅读和学习。通过深入理解和运用这些设计模式,可以提升个人的编程技巧,同时也为团队合作和项目维护...

    研磨设计模式-陈臣.王斌.扫描高清版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) ...

    研磨设计模式 源代码

    《研磨设计模式》是一本深入探讨软件设计模式的经典书籍,源代码包含了书中所讲解的各种设计模式的实际应用示例。设计模式是软件工程中的重要概念,它们是经过反复验证、在特定情境下解决常见问题的有效解决方案。...

    研磨设计模式全部源代码

    这个压缩包“研磨设计模式全部源代码”包含了多种设计模式的实现,这些模式可以帮助开发者写出更可维护、可扩展和可复用的代码。下面将详细讲解其中可能包含的一些重要设计模式及其应用。 1. 工厂模式:这是最简单...

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

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

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

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

    研磨设计模式PDF

    《研磨设计模式》这本书是陈臣和王斌两位作者合作的成果,专注于讲解软件设计中的模式应用。设计模式是软件工程中的一种最佳实践,它总结了在特定上下文中解决问题的常见方法,使得开发者可以复用这些解决方案,提高...

    研磨设计模式 演示源代码

    "研磨设计模式 演示源代码"这个资源包含了对设计模式的详细解释和实例分析,旨在帮助学习者深入理解和应用这些模式。 1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。在资源管理、缓存或者线程池...

Global site tag (gtag.js) - Google Analytics