Builder生成器模式

设计模式简述

设计模式的核心在于提供了相关问题的解决方案,使得人们可以更加简单方便地复用成功的设计和体系结构

生成器模式(创建型设计模式)

意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

生成器模式适用于:

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时

  • 当构造过程必须允许被构造的对象有不同的表示时

具体实例(Java语言)

我们将使用 Builder 模式 编写一个 “文档” 编辑程序。一篇文档应当包含如下结构

● 含有一个标题
● 含有内容(字符串)
● 含有条目项目(列表)

Builder 类中定义了决定文档结构的方法,然后 Director 类使用该方法编写一个具体的文档。

Builder 类是抽象类,它只是声明了抽象方法。它的子类决定了具体编写文档的处理
● MDBuilder 类:使用MD编写文档
● HTMLBuilder 类:使用 HTML 编写文档

1.Builder类

/**
 * 声明编写文档的方法的抽象类
 * 1. makeTitle 编写标题 2. makeString 编写普通文本 3. makeTimes 条目 4. close
 * 完成文档编写的方法
 */
public abstract class Builder {
	public abstract void makeTitle(String title);

	public abstract void makeString(String str);

	public abstract void makeH1(String str);

	public abstract void makeTimes(String[] items);

	public abstract void close();
}

/**
 * 使用 Builder 类中声明的方法来编写文档
 */
class Director {
	private Builder builder;

	public Director(Builder builder) {
		this.builder = builder;
	}

	public void construct() {
		builder.makeTitle("Build Pattern实验");
		builder.makeH1("实验目的");
		builder.makeString("利用Build模式,设计并实现一个能够同时扩展标记语言种类和生成文档种类的文档生成器");
		builder.makeH1("实验内容");
		builder.makeTimes(new String[]{"利用Build模式,设计并实现一个文档生成器。它支持多种标记语言(比如Markdown、Latex,并可以在未来支持其他标记语言),并能生成多种文档,比如html、pdf等。"});
		builder.close();
	}
}

2.MDBuilder

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * MD文本编写文档
 */
public class MDBuilder extends Builder {
    private String filename;
    private PrintWriter writer;

    public void makeTitle(String title) {
        filename = "Build pattern 实验.md";
        try {
            writer = new PrintWriter(new FileWriter(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.println("# " + title);
    }

    public void makeH1(String str) {
        writer.println("## " + str);
    }

    public void makeString(String str) {
        writer.println(str);
    }

    public void makeTimes(String[] items) {
        for (int i = 0; i < items.length; i++) {
            writer.println("* " + items[i]);
        }
    }

    public void close() {
        writer.close();
    }

    public String getResult() {
        return filename;
    }
}

3.HTMLBuilder类

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 使用 HTML 编写文档
 */
public class HTMLBuilder extends Builder {
    private String filename;
    private PrintWriter writer;

    public void makeTitle(String title) {
        filename = "Build pattern 实验.html";
        try {
            writer = new PrintWriter(new FileWriter(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.println("<html><head><title>" + title
                + "</title></head><body>");
        writer.println("<h1>" + title + "</h1>");
    }

    public void makeH1(String str) {
        writer.println("<h1>" + str + "</h1>");
    }

    public void makeString(String str) {
        writer.println("<p>" + str + "</p>");
    }

    public void makeTimes(String[] items) {
        writer.println("<ul>");
        for (int i = 0; i < items.length; i++) {
            writer.println("<li>" + items[i] + "</li>");
        }
        writer.println("</ul>");
    }

    public void close() {
        writer.println("</body></html>");
        writer.close();
    }

    public String getResult() {
        return filename;
    }
}

4.Main类

/**
 * 实际编写文档的是 Builder 类
 */
public class Main {
	public static void main(String[] args) {
		// MD文档生成
		MDBuilder textBuilder = new MDBuilder();
		Director director = new Director(textBuilder);
		director.construct();
		String result = textBuilder.getResult();
		System.out.println(result);

		// HTML文档生成
		HTMLBuilder htmlBuilder = new HTMLBuilder();
		Director director1 = new Director(htmlBuilder);
		director1.construct();
		String result1 = htmlBuilder.getResult();
		System.out.println(result1);
	}
}


 

FreeBuilderJava 1.6  自动生成 Builder 模式。当设计类的构造函数或静态工厂具有多个参数时,Builder 模式是一个不错的选择。—— Effective Java,第二版,第39页背景在 Java 中实现 Builder 模式容易出错和重复。即使是一个简单的四字段类,最基本的构建器 API 需要 39 行代码,如果你不使用像 AutoValue 这样的实用程序来生成值样板,则需要 72 行代码。使用import org.inferred.freebuilder.FreeBuilder; @FreeBuilder public interface Person {   /** Returns the person's full (English) name. */   String name();   /** Returns the person's age in years, rounded down. */   int age();   /** Builder of {@link Person} instances. */   class Builder extends Person_Builder { } }JavaBean convention如果值类型遵循 JavaBean 命名约定,只需在访问器方法前面加上'get'(或者,布尔访问器是'is')。 FreeBuilder 会跟随,并在 setter 方法上添加“set”前缀,以及从 toString 输出中删除前缀。@FreeBuilder public interface Person {   /** Returns the person's full (English) name. */   String getName();   /** Returns the person's age in years, rounded down. */   int getAge();   /** Builder of {@link Person} instances. */   class Builder extends Person_Builder { } } Person person = new Person.Builder()     .setName("Phil")     .setAge(31)     .build(); System.out.println(person);  // Person{name=Phil, age=31} 标签:FreeBuilder
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木芒果呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值