建造者模式
建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。
定义:
将一个复杂对象的构建与它对的表示进行分离,使得同样的构建过程可以创建不同的表示
主要作用
在用户不知道对象的建造过程和细节的情况下就可以创建复杂的对象。(说白了就是把内部的建造过程和细节隐藏起来)
例如:
- 工厂(建造者模式):负责制造汽车(组装过程和细节在工厂内)
- 汽车购买者(用户):你只需要说出你需要的型号(就是对象的类型和内容),然后付钱直接购买即可使用(不需要知道汽车是怎么组装的)
角色分析:
那我们用建房子在说:假设造房简化为如下步骤:
1.打基地 2.钢筋工程 3.铺电线 4.粉刷 等;“如果”要盖一个房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建筑者)过来造房子(产品),最后验收。
具体代码实现
//抽象的建造者: 方法
public abstract class Builder {
abstract void buildA();//地基
abstract void buildB();//钢筋工程
abstract void buildC();//铺电线
abstract void buildD();//粉刷
//完工:得到产品
abstract Product getProduct();
}
```java
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public Product(String buildA, String buildB, String buildC, String buildD) {
this.buildA = buildA;
this.buildB = buildB;
this.buildC = buildC;
this.buildD = buildD;
}
public Product() {
}
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
```java
package builder;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 向上
* @Date: 2020/06/11/9:48
* @Description:
*/
//具体建造者:工人
public class Worker extends Builder {
private Product product;
public Worker(){
product=new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
package builder;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 向上
* @Date: 2020/06/11/9:52
* @Description:
*/
//指挥:核心,负责指挥构建一个工程,工程如何构建,由它决定
public class Director {
public Product build(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
package builder;
/**
* Created with IntelliJ IDEA.
*
* @Auther: 向上
* @Date: 2020/06/11/9:55
* @Description:
*/
public class Test {
public static void main(String[] args) {
//指挥
Director director=new Director();
//指挥 具体的工人完成 产品
Product builder=director.build(new Worker());
System.out.println(builder);
}
}
上面是Builder模式的常规写法,导演类Director在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合
通过静态内部类方式实现零件无序装配构建,这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品
比如:麦当劳的套餐,服务员(具体构建者)可以随意搭配任意几种产品(零件) 组成一款套餐(产品),然后出售给客户。比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加简单灵活。
具体代码:
//建造者
public abstract class Builder {
abstract Builder builderA(String msg); //汉堡
abstract Builder builderB(String msg); //可乐
abstract Builder builderC(String msg); //薯条
abstract Builder builderD(String msg);//甜点
abstract Product getProduct();
}
package builder.demo2;
//产品:套餐
public class Product {
private String BuilderA="汉堡";
private String BuilderB="可乐";
private String BuilderC="薯条";
private String BuilderD="甜点";
public String getBuilderA() {
return BuilderA;
}
public void setBuilderA(String builderA) {
BuilderA = builderA;
}
public String getBuilderB() {
return BuilderB;
}
public void setBuilderB(String builderB) {
BuilderB = builderB;
}
public String getBuilderC() {
return BuilderC;
}
public void setBuilderC(String builderC) {
BuilderC = builderC;
}
public String getBuilderD() {
return BuilderD;
}
public void setBuilderD(String builderD) {
BuilderD = builderD;
}
@Override
public String toString() {
return "Product{" +
"BuilderA='" + BuilderA + '\'' +
", BuilderB='" + BuilderB + '\'' +
", BuilderC='" + BuilderC + '\'' +
", BuilderD='" + BuilderD + '\'' +
'}';
}
}
package builder.demo2;
//具体的构建者
public class Worker extends Builder {
private Product product;
public Worker( ) {
product = new Product();
}
@Override
Builder builderA(String msg) {
product.setBuilderA(msg);
return this;
}
@Override
Builder builderB(String msg) {
product.setBuilderB(msg);
return this;
}
@Override
Builder builderC(String msg) {
product.setBuilderC(msg);
return this;
}
@Override
Builder builderD(String msg) {
product.setBuilderD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
package builder.demo2;
import javax.jws.WebService;
public class Test {
public static void main(String[] args) {
//服务员
Worker worker=new Worker();
//链式编程
Product product=worker.builderA("鸡腿").getProduct();
System.out.println(product.toString());
}
}
优点
- 产品的构建和表示分离,实现了解耦。使用建造者模式可以使客户端不必知道产品内部组成的细节。
- 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
- 具体的构建者类之间是相互独立的,这有利于系统的扩展。增加新的具体构建者无需修改原有类库的代码,符合开闭原则。
缺点
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体的构造者来实现这种变化,导致系统变得很庞大。
应用场景
- 需要生产的产品对象有复杂的内部结构,这些产品对象具备共性;
- 隔离复杂对象的创建和使用,并使得使用的创建过程可以创建不同的产品。
- 适合于一个具有较多的零件(属性)的产品(对象)的创建过程。
多敲多练,多理解就OK!!