建造者模式(Builder Pattern)

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了建造者模式(Builder Pattern)相关的知识,希望对你有一定的参考价值。

建造者模式(Builder Pattern)

建造者模式的定义

指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

建造者模式的优点

  1. 各个具体的建造者相互独立,有利于系统的扩展。
  2. 客户端不必知道产品内部组成的细节,便于控制细节风险。

建造者模式的缺点

  1. 产品的组成部分必须相同,这限制了其使用范围。
  2. 如果产品的内部变化复杂,该模式会增加很多的建造者类。

建造者模式的结构

建造者(Builder)模式的主要角色如下。

  1. 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
  2. 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  3. 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  4. 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

建造者模式的实现

物料部分

package org.donny.design.patterns.builderPattern;

import java.math.BigDecimal;

/**
 * 物料
 */
public interface Matter {

    /**
     * 场景;地板、地砖、涂料、吊顶
     */
    String scene();

    /**
     * 品牌
     */
    String brand();

    /**
     * 型号
     */
    String model();

    /**
     * 平米报价
     */
    BigDecimal price();

    /**
     * 描述
     */
    String desc();
}
package org.donny.design.patterns.builderPattern.matter.ceiling;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 吊顶
 * 品牌;装修公司自带
 * 型号:一级顶
 */
public class LevelOneCeiling implements Matter {

    @Override
    public String scene() {
        return "吊顶";
    }

    @Override
    public String brand() {
        return "装修公司自带";
    }

    @Override
    public String model() {
        return "一级顶";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(260);
    }

    @Override
    public String desc() {
        return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
    }

}
package org.donny.design.patterns.builderPattern.matter.ceiling;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 吊顶
 * 品牌;装修公司自带
 * 型号:二级顶
 */
public class LevelTwoCeiling  implements Matter {

    @Override
    public String scene() {
        return "吊顶";
    }

    @Override
    public String brand() {
        return "装修公司自带";
    }

    @Override
    public String model() {
        return "二级顶";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(850);
    }

    @Override
    public String desc() {
        return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";
    }
    
}
package org.donny.design.patterns.builderPattern.matter.coat;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 涂料
 * 品牌;多乐士(Dulux)
 */
public class DuluxCoat  implements Matter {

    @Override
    public String scene() {
        return "涂料";
    }

    @Override
    public String brand() {
        return "多乐士(Dulux)";
    }

    @Override
    public String model() {
        return "第二代";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(719);
    }

    @Override
    public String desc() {
        return "多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。";
    }
    
}
package org.donny.design.patterns.builderPattern.matter.coat;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 涂料
 * 品牌;立邦
 */
public class LiBangCoat implements Matter {

    @Override
    public String scene() {
        return "涂料";
    }

    @Override
    public String brand() {
        return "立邦";
    }

    @Override
    public String model() {
        return "默认级别";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(650);
    }

    @Override
    public String desc() {
        return "立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。";
    }

}
package org.donny.design.patterns.builderPattern.matter.floor;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 地板
 * 品牌;德尔(Der)
 */
public class DerFloor implements Matter {

    @Override
    public String scene() {
        return "地板";
    }

    @Override
    public String brand() {
        return "德尔(Der)";
    }

    @Override
    public String model() {
        return "A+";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(119);
    }

    @Override
    public String desc() {
        return "DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商";
    }

}
package org.donny.design.patterns.builderPattern.matter.floor;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 地板
 * 品牌:圣象
 */
public class ShengXiangFloor implements Matter {

    @Override
    public String scene() {
        return "地板";
    }

    @Override
    public String brand() {
        return "圣象";
    }

    @Override
    public String model() {
        return "一级";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(318);
    }

    @Override
    public String desc() {
        return "圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。";
    }

}
package org.donny.design.patterns.builderPattern.matter.tile;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 地砖
 * 品牌:东鹏瓷砖
 */
public class DongPengTile implements Matter {

    @Override
    public String scene() {
        return "地砖";
    }

    @Override
    public String brand() {
        return "东鹏瓷砖";
    }

    @Override
    public String model() {
        return "10001";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(102);
    }

    @Override
    public String desc() {
        return "东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶行业榜首。";
    }

}
package org.donny.design.patterns.builderPattern.matter.tile;

import org.donny.design.patterns.builderPattern.Matter;

import java.math.BigDecimal;

/**
 * 地砖
 * 品牌;马可波罗(MARCO POLO)
 */
public class MarcoPoloTile implements Matter {

    @Override
    public String scene() {
        return "地砖";
    }

    @Override
    public String brand() {
        return "马可波罗 (MARCO POLO)";
    }

    @Override
    public String model() {
        return "缺省";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal(140);
    }

    @Override
    public String desc() {
        return "\\"马可波罗\\"品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以文化陶瓷占领市场,享有仿古砖至尊的美誉。";
    }

}

产品部分

package org.donny.design.patterns.builderPattern;

public class Menu {

    private Matter celling;
    private Matter coat;
    private Matter floor;
    private Matter tile;

    private String getDetail;

    public Matter getCelling() {
        return celling;
    }

    public void setCelling(Matter celling) {
        this.celling = celling;
    }

    public Matter getCoat() {
        return coat;
    }

    public void setCoat(Matter coat) {
        this.coat = coat;
    }

    public Matter getFloor() {
        return floor;
    }

    public void setFloor(Matter floor) {
        this.floor = floor;
    }

    public Matter getTile() {
        return tile;
    }

    public void setTile(Matter tile) {
        this.tile = tile;
    }

    public String getGetDetail() {
        return getDetail;
    }

    public void setGetDetail(String getDetail) {
        this.getDetail = getDetail;
    }

}

建造类部分

public abstract class IMenuBuilder {

    public abstract Menu getMenu();
}
public class LuxuryMenuBuilder extends IMenuBuilder {

    private final Menu luxuryMenu = new Menu();
    private final List<Matter> list = new ArrayList<>();
    /**
     * 装修价格
     */
    private BigDecimal price = BigDecimal.ZERO;

    /**
     * 面积
     */
    private final BigDecimal area;

    public LuxuryMenuBuilder(Double area) {
        this.area = new BigDecimal(area);
        this.luxuryMenu.setCelling(new LevelTwoCeiling());
        this.price = this.price.add(this.area.multiply(new BigDecimal("0.2")).multiply(luxuryMenu.getCelling().price()));
        this.luxuryMenu.setCoat(new DuluxCoat());
        this.price = price.add(this.area.multiply(new BigDecimal("1.4")).multiply(luxuryMenu.getCoat().price()));
        this.luxuryMenu.setFloor(new ShengXiangFloor());

        this.list.add(luxuryMenu.getFloor());
        this.list.add(luxuryMenu.getCoat());
        this.list.add(luxuryMenu.getCelling());
        this.luxuryMenu.setGetDetail(this.getDetail());
    }

    @Override
    public Menu getMenu() {
        return luxuryMenu;
    }

    public String getDetail() {
        StringBuilder detail = new StringBuilder("\\r\\n-------------------------------------------------------\\r\\n" +
                "装修清单" + "\\r\\n" +
                "套餐等级:欧式\\r\\n" +
                "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\\r\\n" +
                "房屋面积:" + area.doubleValue() + " 平米\\r\\n" +
                "材料清单:\\r\\n");

        for (Matter matter : this.list) {
            detail.append(matter.scene()).append(":").append(matter.brand()).append("、").append(matter.model()).append("、平米价格:").append(matter.price()).append(" 元。\\n");
        }

        return detail.toString();
    }
}
package org.donny.design.patterns.builderPattern;

import org.donny.design.patterns.builderPattern.matter.ceiling.LevelTwoCeiling;
import org.donny.design.patterns.builderPattern.matter.coat.LiBangCoat;
import org.donny.design.patterns.builderPattern.matter.tile.MarcoPoloTile;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class LightLuxuryMenuBuilder extends IMenuBuilder  {

    private final Menu lightLuxuryMenu = new Menu();
    private final List<Matter> list = new ArrayList<>();
    /**
     * 装修

以上是关于建造者模式(Builder Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)