贵有恒,何必三更起、五更眠、最无益,只怕一日曝、十日寒。这篇文章主要讲述设计模式-- 建造者模式详解相关的知识,希望能为你提供帮助。
开局一张图,剩下全靠写...
引言设计模式集合:http://aphysia.cn/categories/designpattern
如果你用过 ?
?Mybatis?
? ,相信你对以下代码的写法并不陌生,先创建一个??builder?
?对象,然后再调用??.build()?
?函数:
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
上面其实就是我们这篇文章所要讲解的 建造者模式,下面让我们一起来琢磨一下它。
什么是建造者模式建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(来源于百度百科)
建造者模式,其实是创建型模式的一种,也是23种设计模式中的一种,从上面的定义来看比较模糊,但是不得不承认,当我们有能力用简洁的话去定义一个东西的时候,我们才是真的了解它了,因为这个时候我们已经知道它的界限在哪。所谓将一个复杂对象的构建与它的表示分离,就是将对象的构建器抽象出来,构造的过程一样,但是不一样的构造器可以实现不一样的表示。
结构与例子建造者模式主要分为以下四种角色:
说到这里,可能会有点懵,毕竟全都是定义,下面从实际例子来讲讲,就拿程序员最喜欢的电脑来说,假设现在要生产多种电脑,电脑有屏幕,鼠标,cpu,主板,磁盘,内存等等,我们可能立马就能写出来:?Product?
?):具体生产器要构造的复杂对象?Bulider?
?):抽象生成器是一个接口,创建一个产品各个部件的接口方法,以及返回产品的方法?ConcreteBuilder?
?):按照自己的产品特性,实现抽象建造者对应的接口?Director?
?):创建一个复杂的对象,控制具体的流程
public class Computer {
private String screen;
private String mouse;
private String cpu;
private String mainBoard;
private String disk;
private String memory;
...
public String getMouse() {
return mouse;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
...
}
上面的例子中,每一种属性都使用单独的??set?
?方法,要是生产不同的电脑的不同部件,具体的实现还不太一样,这样一个类实现起来貌似不是很优雅,比如联想电脑和华硕电脑的屏幕的构建过程不一样,而且这些部件的构建,理论上都是电脑的一部分,我们可以考虑流水线式的处理。当然,也有另外一种实现,就是多个构造函数,不同的构造函数带有不同的参数,实现了可选的参数:
public class Computer {
private String screen;
private String mouse;
private String cpu;
private String mainBoard;
private String disk;
private String memory;
public Computer(String screen) {
this.screen = screen;
}
public Computer(String screen, String mouse) {
this.screen = screen;
this.mouse = mouse;
}
public Computer(String screen, String mouse, String cpu) {
this.screen = screen;
this.mouse = mouse;
this.cpu = cpu;
}
...
}
上面多种参数的构造方法,理论上满足了按需构造的要求,但是还是会有不足的地方:
首先,我们先用流水线的方式,实现按需构造,不能重载那么多构造函数:
public class Computer {
private String screen;
private String mouse;
private String cpu;
private String mainBoard;
private String disk;
private String memory;
public Computer setScreen(String screen) {
this.screen = screen;
return this;
}
public Computer setMouse(String mouse) {
this.mouse = mouse;
return this;
}
public Computer setCpu(String cpu) {
this.cpu = cpu;
return this;
}
public Computer setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
return this;
}
public Computer setDisk(String disk) {
this.disk = disk;
return this;
}
public Computer setMemory(String memory) {
this.memory = memory;
return this;
}
}
使用的时候,构造起来,就像是流水线一样,一步一步构造就可以:
Computer computer = new Computer()
.setScreen("高清屏幕")
.setMouse("罗技鼠标")
.setCpu("i7处理器")
.setMainBoard("联想主板")
.setMemory("32G内存")
.setDisk("512G磁盘");
【设计模式-- 建造者模式详解】但是以上的写法不够优雅,既然构造过程可能很复杂,为何不用一个特定的类来构造呢?这样构造的过程和主类就分离了,职责更加清晰,在这里内部类就可以了:
package designpattern.builder;
import javax.swing.*;
public class Computer {
private String screen;
private String mouse;
private String cpu;
private String mainBoard;
private String disk;
private String memory;
Computer(Builder builder) {
this.screen = builder.screen;
this.cpu = builder.cpu;
this.disk = builder.disk;
this.mainBoard = builder.mainBoard;
this.memory = builder.memory;
this.mouse = builder.mouse;
}
public static class Builder {
private String screen;
private String mouse;
private String cpu;
private
推荐阅读
- AIOps探索揭秘日志异常检测新方法
- pm2 重启策略(restart strategies)
- 基于云开发的答题活动小程序v2.0-实现微信授权登录功能
- 部署YUM源仓库与NFS共享存储服务
- 存储数据恢复案例存储断电后重启失败,虚拟机启动失败的数据恢复
- 带你了解Typescript的14个基础语法
- C语言算法和数据存储
- Redis 很屌,不懂使用规范就糟蹋了
- dart系列之:时间你慢点走,我要在dart中抓住你