1. 背景
要理解建造者模式,首先要理解农民工建筑模式。
农民工建筑模式就是靠经验,对怎么盖这个屋子心里大体有个数,优点就是自由灵活成本低,效果就是你很难掌控其中的每一个环节。比如建筑施工前必须先安装防尘网和保护施工人员的拦网,这个基本规定都有可能无法落实。这种模式我称之为原始建造模式。
建造者模式就厉害了,它是制度化运营,必须得有个人现场指挥,这个人非常了解建造流程,而且要求所有施工人员必须按照流程来。这样肯定成本高了点,毕竟至少多了一个人要给他发工资,但是确实在规范性、安全性方面得到提高。这种是正儿八经的建造者模式。
2. 原始建造模式
在我们日常的项目中,有一个事情跟这个模型很像,就是数据库连接对象的创建。
按照正常流程就是:
//mysql建造
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/test";
String name = "root";
String pwd = "root";
conn = DriverManager.getConnection(url,name ,pwd);
//oracle建造
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@//127.0.0.1:1521/orcl";
String name = "root";
String pwd = "root";
conn = DriverManager.getConnection(url,name ,pwd);
如果中间少了哪一步,比如name忘了赋值,这个可能就要有问题了。而且流程高度相似,完全可以请一个专业人员来管控这个流程。此处用建造者模式来改造上述流程。
3. 正儿八经的建造者模式
OK,首先我们确定我们建造的对象是Connection,建造行为可定义为ConnectionBuilder抽象类,因为不管什么Connection建造都是可以由这个抽象类描述的:
/**
* 建造行为接口
*/
public abstract class ConnectionBuilder {
protected String driver;
protected String url;
protected String name;
protected String password;
public abstract void buildDriver();
public abstract void buildUrl();
public abstract void buildName();
public abstract void buildPassword();
public abstract Connection createConnection() throws Exception;
}
然后我们请一个指挥官,这个指挥官非常了解Connection建造流程,只要他出手,必按流程走:
/**
* 建造指挥官
*/
public class ConnectionDirector {
public Connection construct(ConnectionBuilder builder) throws Exception {
builder.buildDriver();
builder.buildUrl();
builder.buildName();
builder.buildPassword();
return builder.createConnection();
}
}
然后来了个具体的建造任务,是要建造一个Mysql的连接对象,而且任务清单也出来了:
public class MysqlConnectionBuilder extends ConnectionBuilder {
//每个方法表示建造过程中一个步骤/任务
@Override
public void buildDriver() {
this.driver = "com.mysql.jdbc.Driver";
}
@Override
public void buildUrl() {
this.url = "jdbc:mysql://127.0.0.1:3306/test";
}
@Override
public void buildName() {
this.name = "root";
}
@Override
public void buildPassword() {
this.password = "root";
}
@Override
public Connection createConnection() throws Exception {
Class.forName(this.driver);
return DriverManager.getConnection(url, name, password);
}
}
OK,此时如果我们自己建,比如直接调用createConnection,就会忽略流程,可能有问题。
所以我们利用建造者模式,请指挥官来建:
public static void main(String[] args) throws Exception {
ConnectionDirector director=new ConnectionDirector();
Connection mysqlCon=director.construct(new MysqlConnectionBuilder());
}
4. 作用
用了指挥官之后,看似麻烦了,实际可拓展性更好了,比如再来个oracle、sqlserver数据库,照样给你建了,而且保证正确。
实际上设计模式就是通过语法的一些限制,保证一些事情的安全顺利执行。