JAVA设计模式:建造者(Builder)
????? 创建对象的方法很多,常见的有构造函数,静态工厂方法,工厂方法等。以上三种方法不适合创建需要提供多个参数的对象,而其中某些参数是可选的场景。读者可能会想到通过空的构造方法先构建一个对象的雏形,然后调用getter和setter方法向对象内部注入状态数据。这种方式看似很不错,但还是可能存在对象的状态数据未完全写入前对象已被使用的风险。
?
????? 建造者模式将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
?
????? 建造者模式涉及到的三个角色:
产品:被建造的对象;建造者:抽象产品的建造过程;导演者:按需要建造不同的产品。????? 以网上经典的创建文件的过程为例子,先来看要创建的产品,即文件对象,一个文件由三部分组成:
?
public class MyFile { private String head; private String content; private String end; public void setFcontent(Strig content) { this.content = content; } public void setEnd(String end) { this.end = end; } public void setHead(String head) { this.head = head; } public void write(String path) throws IOException{ File f=new File(path); PrintWriter out=new PrintWriter(new FileWriter(f)); out.println(head); out.println(content); out.println(end); out.close(); }}
?
???? 再来看创建者,这里是一个接口:
?
public interface FileBuilder { void buildHead(); void buildContent(); void buildEnd(); MyFile getResult();}
?
???? 最后是导演者,用来实施对象的创建过程:
?
public class FileDirector { private FileBuilder filebuilder; public FileDirector(FileBuilder filebuilder){ this.filebuilder=filebuilder; } public MyFile construct(){ filebuilder.buildHead(); filebuilder.buildContent(); filebuilder.buildEnd(); return filebuilder.getResult(); }}
?
???? 两个具体的创建者,分别用来创建XML文件和TXT文件:
?
public class XmlFileBuilder implements FileBuilder{ private MyFile file = new MyFile();; public void buildHead() { file.setHead("<?xml version="1.0"?><content>"); } public void buildContent() { file.setContent("<node>value</node>"); } public void buildEnd() { file.setEnd("</content>"); } public MyFile getResult() { return file; }}public class TxtFileBuilder implements FileBuilder{ private MyFile file = new MyFile();; public void buildHead() { file.setHead("this it the txt file head"); } public void buildContent() { file.setContent("this it the txt file content"); } public void buildEnd() { file.setEnd("this it the txt file end"); } public MyFile getResult() { return file; }}
?
????? 最后是测试代码:
?
public void test(){ FileBuilder builder = new XmlFileBuilder(); FileDirector director = new FileDirector(builder); MyFile file = director.construct(); //省略了使用对象的代码}
?
????? 看上面的代码,我们可以通过替换builder的实现来创建不同的对象,对象的创建过程得到了非常好的隐藏,并且不会暴露未创建完的对象。
?
????? 作为开发者,你一定使用过JDK提供的工具类StringBuilder或StringBuffer,事实上StringBuilder和StringBuffer使用的正是建造者模式。
?