一只烤鸭朝北走

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  定义:建造者模式也称为生成器模式,将一个个简单对象一步步构造成一个复杂的对象,将复杂对象的构建和它的表示分离,使得同样的构建过程有不同的表示;

  主要解决:系统中复杂对象的创建过程,通常由各个部分的子对象采用一定的算法构成;由于需求的变化 ,这个复杂对象的各个部分通常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定;

  何时使用:一些基本部件不变,而其组合经常变化的时候;

  如何解决:将变与不变相分离;

   模式结构(PS:本图是从网上找过来的):

  

  模式角色分析:

    1、产品类:是一个较为复杂的对象,这个对象的创建过程较为复杂,实际编程中可以由一个抽象类和它的不同实现组成,也可以由抽象类与他们的实现组成;

    2、抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交给它的子类来实现,这样更容易扩展,同时也符合面向接口编程的出发点,一般包含两个抽象方法,一个用来建造产品,一个用来返回产品;

    3、建造者:实现抽象类所有未实现的方法,组件产品,返回组装好的产品;

    4、指挥类:负责调用适当的建造者来组建产品,指挥类一般不与产品类发生依赖关系,与指挥类直接交互的是建造者类,一般来说指挥类被用来封装程序中易变的部分;

  应用场景:

  1、创建复杂对象的算法独立于组成对象的部件;

  2、肯德基的汉堡、可乐、薯条、炸鸡等是不变的,而其组合是经常变化的,将不同的产品组合在一起,生成出来所谓的“套餐”;

  3、jdk中的StringBuilder类;

  4、同一个创建过程需要有不同的内部属性的产品对象,例如建造房子,利用沙子、水泥、钢筋既可以建造别墅也可以建造普通楼房;

  优点:

  1、客户端不必知道产品组成的细节,将产品本身与产品的创建过程,使得相同的创建过程可以创建不同的产品对象;

  2、每个具体建造者都独立,因此可以方便地更换、或者增加具体的建造者,用户使用不同的具体建造者可以得到不同的产品对象;

  3、可以更精细地控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰;

  4、增加新的具体的建造者不需要修改原来类库的代码,指挥类针对抽象建造者类编程,系统方便扩展,符合“开闭原则”;

  缺点:

  1、建造者过多时,会产生很多类,难以维护;

  2、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品之间的差异性很大,则不适合使用该模式,使用范围受限;

  工厂模式和建造者模式联系和区别:

  工厂模式重点关注如何获取实例对象,而建造者模式重点关注如何建造实例对象;建造者模式和工厂模式从总体上看仅仅是多了一个“指挥类”的角色,如果将“指挥类”看做是最终调用的客户端,那么剩余部分就可以看做是一个简单的工厂模式了,工厂模式是将实例对象的建造过程封装在工厂中了,工厂直接返回实例对象给调用者,而建造者模式是将实例对象的建造过程封装在了具体的建造者类中,由“指挥类”调用,返回对象给客户端调用;

  UML类图:

  

  示例代码:

package cn.com.pep.model.builder.builder2;
/**
 * 
 * @Title: Builder  
 * @Description:  抽象建造者
 * @author wwh 
 * @date 2022-9-1 9:56:08
 */
public abstract class Builder {
    
    /**
     * 
     * @Title: builderPartA 
     * @Description:
     */
    public abstract void builderPartA();
    
    /**
     * 
     * @Title: builderPartB 
     * @Description:
     */
    public abstract void builderPartB();
    
    /**
     * 
     * @Title: getProduct 
     * @Description:  
     * @return
     */
    public abstract Product getProduct();
}

 

package cn.com.pep.model.builder.builder2;
/**
 * 
 * @Title: ConcreteBuilderA  
 * @Description:  具体建造者A
 * @author wwh 
 * @date 2022-9-1 10:00:40
 */
public class ConcreteBuilderA extends Builder{
    
    private Product product = new Product();

    @Override
    public void builderPartA() {
        product.addPart("VegetableBurger");
    }

    @Override
    public void builderPartB() {
        product.addPart("Cocacola");
    }

    @Override
    public Product getProduct() {
        return product;
    }

    
}
package cn.com.pep.model.builder.builder2;
/**
 * 
 * @Title: ConcreteBuilderB  
 * @Description:  具体建造者B
 * @author wwh 
 * @date 2022-9-1 10:04:48
 */
public class ConcreteBuilderB extends Builder{
    
    private Product product = new Product();

    @Override
    public void builderPartA() {
        // TODO Auto-generated method stub
        product.addPart("ChickenBurger");
    }

    @Override
    public void builderPartB() {
        // TODO Auto-generated method stub
        product.addPart("Pepsi");
    }

    @Override
    public Product getProduct() {
        // TODO Auto-generated method stub
        return product;
    }

}
package cn.com.pep.model.builder.builder2;

/**
 * 
 * @Title: Product  
 * @Description:  
 * @author wwh 
 * @date 2022-9-1 9:50:03
 */

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * 
 * @Title: Product  
 * @Description:  产品类
 * @author wwh 
 * @date 2022-9-1 9:55:50
 */
public class Product {

    List<String> parts = new ArrayList<>();

    /**
     * 
     * @Title: addPart
     * @Description: 添加产品部件
     * @param part
     */
    public void addPart(String part) {
        parts.add(part);
    }

    /**
     * 
     * @Title: show
     * @Description:显示产品细节
     */
    public void show() {
        Iterator<String> it = parts.iterator();
        while (it.hasNext()) {
            String string = (String) it.next();
            System.err.println(string);
        }
    }

}
package cn.com.pep.model.builder.builder2;
/**
 * 
 * @Title: Director  
 * @Description:  指挥者类
 * @author wwh 
 * @date 2022-9-1 10:12:05
 */
public class Director {
    
    /**
     * 
     * @Title: creatProduct 
     * @Description:  
     * @param builder
     */
    public void creatProduct(Builder builder) {
        builder.builderPartA();
        builder.builderPartB();
    }
}
package cn.com.pep.model.builder.builder2;
/**
 * 
 * @Title: BuilderPatternDemo  
 * @Description:  测试类
 * @author wwh 
 * @date 2022-9-1 10:13:51
 */
public class BuilderPatternDemo {
    
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilderA();
        Director director = new Director();
        director.creatProduct(builder);
        Product p = builder.getProduct();
        p.show();
        
        builder = new ConcreteBuilderB();
        director.creatProduct(builder);
        p = builder.getProduct();
        p.show();
        
    }
}
posted on 2022-09-01 11:09  一只烤鸭朝北走  阅读(123)  评论(0编辑  收藏  举报