组装复杂实例的 Builder模式

Builder模式

应用场景

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

本质

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

优点

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

缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

角色

  • 建造者(Builder) 角色:
    定义创建一一个Product对象所需的各个部件的操作

  • 具体建造者(Concrete Builder)角色:
    实现Builder角色提供的接口,一步一步完成创建产品实例的过程。
    在建造过程完成后,提供产品的实例。

  • 指导者(Director)角色:
    主要用来使用 Builder接口,以一个统一的过程来构建所需要的Product对象,只调用在Builder角色中被定义的方法。

  • 产品(Product)角色:
    产品便是建造中的复杂对象。

Builder模式的类图

在这里插入图片描述

示例程序

示例程序的类图

在这里插入图片描述

示例代码
public abstract class Builder {
	
	public abstract void makeHead(String str);
	public abstract void makeBody(String[] str);
	public abstract void makeEnd(String str);
	public abstract void close();
}
public class Director {

	private Builder builder;

	public Director(Builder builder) {
		this.builder = builder;
	}
	public void construct() {
		builder.makeHead("901645165,2020416");
		builder.makeBody(new String [] {
				"数据1","数据2"
		});
		builder.makeEnd("Liu Dawei");
		builder.close();
	}
}
public class TextBuilder extends Builder {

	private StringBuffer buffer=new StringBuffer();
	
	@Override
	public void makeHead(String str) {
		buffer.append("文件头:"+str);
		buffer.append("\n");
	}

	@Override
	public void makeBody(String[] str) {
		for(int i=0;i<str.length;i++) {
			buffer.append("  "+str[i]);
		}
		buffer.append("\n");
	}

	@Override
	public void makeEnd(String str) {
		buffer.append("输出人"+str);
	}

	@Override
	public void close() {
		return;
	}

	public String getResult() {
		return buffer.toString();
	}
}
public class XMLBuilder extends Builder {

	private String filename;
	private PrintWriter writer;
	
	@Override
	public void makeHead(String str) {
		filename = "111.xml";
		try {
			writer = new PrintWriter(new FileWriter(filename));
		} catch (IOException e) {
			e.printStackTrace();
		}
		writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?><bookstore>");
		writer.println("<name>" + str + "</name>");
	}

	@Override
	public void makeBody(String[] str) {
		for (int i = 0; i < str.length; i++) {
			writer.println("<name>" + str[i] + "</name>");
			writer.println("</bookstore>");
		}

	}

	@Override
	public void makeEnd(String str) {
		
		writer.println("<name>"+str+"</name>");
		
	}

	@Override
	public void close() {}

	public String getResult() {
		return writer.toString();
	}

}
public class Main {

	public static void main(String[] args) {
		if(args.length!=1) {
			usage();
			System.exit(0);
		}
		if (args[0].equals("Text")) {
			TextBuilder textBuilder = new TextBuilder();
			Director director = new Director(textBuilder);
			director.construct();
			String result = textBuilder.getResult();
			System.out.println(result);
		}else if(args[0].equals("XML")) {
			XMLBuilder xmlbuilder = new XMLBuilder();
            Director director = new Director(xmlbuilder);
            director.construct();
            String filename = xmlbuilder.getResult();
            System.out.println(filename + "文件编写完成。");
		}else {
           usage();
           System.exit(0);
       }
		
	}

	private static void usage() {
		System.out.println("Usage: Java Main Text");
		System.out.println("Usage: Java Main XML");
	}

}

拓展思路

  • Director决定了Builder角色中方法的调用顺序。

相关设计模式

  • Template Method模式
    在Builder模式中,Director 角色控制Builder角色。
    在Template Method模式中,父类控制子类。

  • Composite 模式
    有些情况下Builder模式生成的实例构成了Composite模式。

  • Abstract Factory模式
    Builder模式和Abstract Factory模式都用于生成复杂的实例。

  • Facade模式
    在Builder模式中,Director 角色通过组合Builder角色中的复杂方法向外部提供可以简单生成实例的接口( API)(相当于示例程序中的construct方法)。
    Facade模式中的Facade角色则是通过组合内部模块向外部提供可以简单调用的接口(API)

满足的原则

  • 开放封闭原则
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值