【设计模式】建造者(生成器Builder)模式

将一个复杂对象的构件与它的表示分离,是的同样的构建可以创建不同的表示。

对象性质的建造

  • 有些情况下,一个对象会有一些重要的性质,在它们没有恰当的值之前,对象不能作为一个完整的产品使用。
  • 有些情况下,一个对象的一些性质必须按照某个顺序复制才有意义。在某个性质没有赋值之前,另一个性质则无法赋值。这些情况是的性质本身的建造涉及到复杂的商业逻辑。
    这时候,此对象相当于一个有待建造的产品,而对象的这些性质相当于产品的零件,建造产品的过程就是组合零件的过程。由于组合零件的过程很复杂,因此,这些“零件”的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个全部零件都建造完毕的产品对象

思路

  • 先把构建过程独立出来,在建造者模式中把它称为指导者,由他来知道装配过程。但不负责每步具体的实现。
  • 要有能具体实现每步的对象,称之为建造者或者生成器。

建造者模式的结构

在这里插入图片描述

  • 建造者(Builder)角色
    定义创建一个Product对象所需的各个部件的操作。
  • 具体建造者(Concrete Builder)角色
    实现Builder角色提供的接口,一步一步完成穿件产品实例的过程。
    在建造过程完后才能后,提供产品的实例。
  • 指导者(Director)角色
    主要用来使用Builder接口,以一个统一的过程来构件所需要的Product对象。
  • 产品(Product)角色
    产品便是建造中的复杂对象。

客户端作用

客户端负责创建指导者和具体建造者对象。然后,客户端把具体建造者对象交给指导者。客户一声令下,指导者操纵建造者开始创建产品。当产品创建完成后,建造者把产品返还给客户端。

在什么情况下使用建造者模式

  • 需要生成的产品对象有复杂的内部结构。
  • 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
  • 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到。

优点

  • 建造者模式的使用是的产品的内部表象可以独立的变化。使用建造者模式可以使客户端不必知道产品内部组成的细节。
  • 每一个Builder都相对立,而与其他的Builder无关。
  • 模式所建造的最终产品更易于控制。

本质

分离整体构建算法和部件构造。

实例

【问题】
继续工厂方法章节的补充例子,用建造者模式实现(代码+UML图) :
(1) 导出数据的应用框架,通常对于具体的导出内容和格式是有要求的:分成三部分,文件头、文件体、文件尾
文件头:分公司编号、导出数据的日期,对于文本格式,中间用逗号分离
文件体:表名称,然后分条描述数据。
文件尾:输出人
(2)不管是输出文本文件,还是输出XML文件,步骤基本一致
先拼接文件头的内容
然后拼接文件体的内容
在拼接文件尾的内容
最后把拼接好的内容输出去成为文件

【代码】
ps:理解有些问题,代码可能有问题。

public abstract class FileExport {
	
	public abstract void WriteHead(String num);
	public abstract void WriteMain(String name,String data);
	public abstract void WriteTail(String person);

}
public class XMLExport extends FileExport {

	@Override
	public void WriteHead(String num) {
		Date date = new Date(0);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String createdate = sdf.format(date);
		String overall="表编号:"+num+",建表日期:"+createdate;
		System.out.println("输出到XML头部:"+overall);
	}

	@Override
	public void WriteMain(String name, String data) {
		String overall="表名:"+name+",表中数据:"+data;
		System.out.println("输出到XML主体:"+overall);
	}

	@Override
	public void WriteTail(String person) {
		String overall="输出人:"+person;
		System.out.println("输出到XML尾部:"+overall);
	}

}
public class TxtExport extends FileExport {
	
	String filePath =null;
	File file=null;
	BufferedWriter br = null;
	FileWriter fr = null;
	
	public TxtExport() {}

	public TxtExport(String filePath, File file, BufferedWriter br,
			FileWriter fr) {
		super();
		this.filePath = filePath;
		this.file = file;
		this.br = br;
		this.fr = fr;
	}

	@Override
	public void WriteHead(String num) {
	
		Date date = new Date(0);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String createdate = sdf.format(date);
		String overall="表编号:"+num+",建表日期:"+createdate;

		try {
			fr = new FileWriter(file, true);
			br = new BufferedWriter(fr);
			br.newLine();
			br.write(overall);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void WriteMain(String name,String data) {
		String overall="表名:"+name+",表中数据:"+data;
		try {
			fr = new FileWriter(file, true);
			br = new BufferedWriter(fr);
			br.newLine();
			br.write(overall);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void WriteTail(String person) {
		String overall="输出人:"+person;
		try {
			fr = new FileWriter(file, true);
			br = new BufferedWriter(fr);
			br.newLine();
			br.write(overall);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
public class Director {
	
	FileExport fep;
	
	public Director(FileExport fep) {
		super();
		this.fep = fep;
	}

	public Director() {}

	public void Export(String num,String name,String data,String person)
    {
       fep.WriteHead(num);
       fep.WriteMain(name, data);
       fep.WriteTail(person);
    }

}
public class Cliect {

	public static void main(String[] args) {
		String filePath = "D:\\APPS\\JAVA WORKPLACE\\SJMS_08\\src\\Builder\\test.txt";
		File file = new File(filePath);
		BufferedWriter br = null;
		FileWriter fr = null;
		FileExport tep=new TxtExport(filePath,file,br,fr);
		FileExport xep=new XMLExport();
		
		Director d1=new Director(tep);
		d1.Export("1", "设计模式", "数据1", "小菜");
		Director d2=new Director(xep);
		d2.Export("2", "设计模式", "数据2", "大鸟");
	}

}

【UML图】
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值