java设计模式之建造者模式(四)

昨天已经过去,即使昨天发生了再美的事情,我们也无法让它重新来过,明天还未来到,你把未来想象的像花一样那也是以后的事情,纵使你的手在长也无法抓到,我们唯一能够抓得到,掌控的了的就是今天。

设计模式学习,近期我会把23中设计模式都写成博客,敬请期待~

定义

将一个复杂的对象与他的细节(实现代码)分离,使得同样的创建过程可以表示不同的样式.

百度百科

使用场景

设计同一种类型不同的样式,根据提出的需求而返回具体的值

比如说我现在要要买一辆汽车,我提出要求是车门必须是红色的,他给我车的时候车门就必须是红色的.

分类

  • 不可以自定义各种样式,但可以设置先后出场顺序
    比如:去吃肯德基,我可以先吃汉堡在喝可乐,也可以先喝可乐在吃汉堡,但是不能浪费,吃了汉堡可乐就丢掉了,喝了可乐汉堡就丢掉了,这样是不允许的
  • 可以随意设置出场先后顺序,各种样式等(推荐)

方式一

不可以自定义各种样式,但可以设置先后出场顺序

整体思路:

假设我现在要盖房子,我需要吧房子给到一个指挥盖房子的人,这里称之为总指挥,总指挥拟定好盖房方案之后分配给工人盖房,步骤为:

  • 打地基
  • 钢筋混凝土
  • 铺地砖
  • 粉刷

这是房子的的四步

UML类图理解:

UML类图(1.1):

分析:

  • Builder是具体创建房子的细节(抽象类)
  • House是最终要得到的房子(产品)
  • Worker是工人,负责实现房子的搭建
  • TotalCommand是总指挥,我给你房子步骤(Builder),你返回我房子(这里Worker继承自Builder)

具体代码实现:

Builder类:盖房步骤:

public abstract class Builder {
    
    
    abstract void createA();//地基
    abstract void createB();//钢筋混凝土
    abstract void createC();//铺地砖
    abstract void createD();//粉刷
    //产品
    abstract House getHouse();
}

House类,最终产品:

public class House {
    
    
    public String A = "地基";
    public String B = "混凝土";
    public String C = "铺地砖";
    public String D = "粉刷";
}

Worker工人实现类:

public class Worker extends Builder {
    
    
    private final House house;
    
    public Worker() {
    
    
        house = new House();
    }
    @Override
    void createA() {
    
    
        house.A = "打陨石地基";
        Log.i("指挥者模式:","打陨石地基");
    }
    @Override
    void createB() {
    
    
        house.B = "黄金混凝土";
        Log.i("指挥者模式:","黄金混凝土");
    }
    @Override
    void createC() {
    
    
        house.C = "铺钻石地砖";
        Log.i("指挥者模式:","铺钻石地砖");
    }
    @Override
    void createD() {
    
    
        house.D = "美金粉刷";
        Log.i("指挥者模式:","美金粉刷");
    }
    @Override//返回具体产品
    House getHouse() {
    
    
        return house;
    }
}

TotalCommand类:总指挥:

public class TotalCommand {
    
    

    //返回产品
    public House build(Builder builder){
    
    
        builder.createA();

        builder.createB();

        builder.createC();

        builder.createD();

        return builder.getHouse();
    }
}

实现代码:

//总指挥
TotalCommand totalCommand = new TotalCommand();

//总指挥吧具体实现步骤的工人传进去,最终得到House房子(产品)类
 House house = totalCommand.build(new Worker());

效果图(2.1):


可以看到,产品根据步骤先后执行,

如果说我想刷粉,然后在铺地砖怎么办?

通知总指挥(TotalCommand)修改建房方案

public class TotalCommand {
    
    
    //返回产品
    public House build(Builder builder){
    
    
        builder.createD();
        builder.createC();
        builder.createA();
        builder.createB();
        return builder.getHouse();
    }
}

效果图(2.2):

这种方法常用于比较固定的代码,比如上面说的建房子,你就必须先打地基,在进行之后的操作,

方式二

可以随意设置出场先后顺序,各种样式等(推荐)

整体思路:

  • 方式一的方法是把’导演者(代码流程)'给到了代码来实现,咋们不能随意改变整体的流程;
  • 现在方式二是想把导演者给到我们自己,可以随意改变先后的出场顺序

假设我们现在在吃肯德基:

我是不是可以先吃汉堡,在喝可乐,然后在吃薯条,吃鸡腿?
那万一薯条先上来我肯定得先唑两口吧o(╥﹏╥)o~
这就是先后顺序的问题,没有像建房子一样我必须先打地基然后在干嘛干嘛的.这样就很灵活

UML(类图1.2):


代码实现:

Builder2类 需要实现的食物:

public abstract class Builder2 {
    
    
    public abstract Builder2 createA(String msg);//汉堡
    public abstract Builder2 createB(String msg);//薯条
    public abstract Builder2 createC(String msg);//可乐
    public  abstract Builder2 createD(String msg);//鸡翅

    public abstract Product buildProduct();//具体食物细节
}

Product具体食物代码实现:

public class Product {
    
    
    private   String  A;//汉堡
    private  String  B;//薯条
    private  String  C;//可乐
    private  String  D;//鸡翅

    public String getA() {
    
    
        return A;
    }
    public void setA(String a) {
    
    
        A = a;
    }
    public String getB() {
    
    
        return B;
    }
    public void setB(String b) {
    
    
        B = b;
    }
    public String getC() {
    
    
        return C;
    }
    public void setC(String c) {
    
    
        C = c;
    }
    public String getD() {
    
    
        return D;
    }
    public void setD(String d) {
    
    
        D = d;
    }
    @Override
    public String toString() {
    
    
        return "Waiter{" +
                "A='" + A + '\'' +
                ", B='" + B + '\'' +
                ", C='" + C + '\'' +
                ", D='" + D + '\'' +
                '}';
    }
}

Maker 制造者,制造食物:

public class Maker extends Builder2 {
    
    
    private final Product product;

    public Maker() {
    
    
        product = new Product();
    }
    @Override
   public Builder2 createA(String msg) {
    
    
        product.setA(msg);
        return this;
    }
    @Override
    public  Builder2 createB(String msg) {
    
    
        product.setB(msg);
        return this;
    }
    @Override
    public   Builder2 createC(String msg) {
    
    
        product.setC(msg);
        return this;
    }
    @Override
    public Builder2 createD(String msg) {
    
    
        product.setD(msg);
        return this;
    }
    @Override
  public Product buildProduct() {
    
    
        return product;
    }
}

实现代码:

 //制造者
 Maker maker = new Maker();

        //制造者创建产品
Product product =
       maker.createA("黄金汉堡").
       createB("牛杯薯条").
       createC("长生不老可乐").
       createD("凤凰鸡翅").
       buildProduct();

Log.i("建造者模式:", "product :" + product.toString());

效果图(2.3):

建造者模式与抽象工厂模式对比

  • 建造者返回的是一个建造好的完整产品,抽象工厂返回的是一个相关的产品,这些产品位于不同的产品系列,产生一个’产品族’;
  • 抽象工厂中,客户端实例化工厂类,然后调用工厂类获得对应的产品方法,建造模者模式是直接跨过产品系列直接生产对应的对象.

简单来说就是抽象工厂是生产的工厂,建造者是工厂里面的工人,直接生产对应的产品.我买一辆奥迪,我去总工厂,找到奥迪系列然后生产奥迪车,这是抽象工厂,奥迪车是如何创建的,比如车门,轮胎,发动机等等,创建奥迪车的就是建造者模式

工厂模式学习:包括工厂方法和抽象工厂:java设计模式之工厂模式(二)

总结:
建造者模式大致分为2种方式:

  • 方式一:生产流程固定,按照生产流程生产,不可随意更改流程,灵活性不高,常用于’建房’代码实现
  • 方拾二:生产流程不固定,可随意控制产品出场先后顺序等,灵活度到!

到这里创建型模式就学完了,接下来学习结构型模式

完整代码

最近文章:

java 设计模式之单例模式(一)

java设计模式之工厂模式(二)

java 设计模式之原型模式(三)

java 设计模式之适配器模式(五)

去设计模式/设计原则目录页

原创不易,点个赞支持一下吧~

猜你喜欢

转载自blog.csdn.net/weixin_44819566/article/details/112356907