文章參考書籍:重學Java設計模式
作者:⼩傅哥
場景:
模擬裝修公司對於設計出⼀些套餐裝修服務的。
很多裝修公司都會給出⾃家的套餐服務,⼀般有;歐式豪華、輕奢⽥園、現代簡約等等,⽽這些套餐的後⾯是不同的商品的組合。例如;⼀級&⼆級吊頂、多樂⼠塗料、聖象地板、⻢可波羅地磚等等,按照不同的套餐的價格選取不同的品牌組合,最終再按照裝修⾯積給出⼀個整體的報價。這⾥我們就模擬裝修公司想推出⼀些套餐裝修服務,按照不同的價格設定品牌選擇組合
傳統方式實現
物料接口
import java.math.BigDecimal;
/**
* 物料接口
* 提供物料的基本信息
*/
public interface Matter {
/**
* 場景:地板、地磚、吊頂、塗料
* @return
*/
String scene();
/**
* 品牌
* @return
*/
String brand();
/**
* 型號
* @return
*/
String model();
/**
* 價格
* @return
*/
BigDecimal price();
/**
* 描述
* @return
*/
String desc();
}
一級吊頂
import com.ustcinfo.strategy.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(200);
}
@Override
public String desc() {
return "造型只做低一級,只有一個層次的吊頂,一般離頂120-150mm";
}
}
二級吊頂
import com.ustcinfo.strategy.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(800);
}
@Override
public String desc() {
return "兩個層次的吊頂,⼆級吊頂⾼度⼀般就往下吊20cm,要是層⾼很⾼,也可增加\n" +
"每級的厚度";
}
}
塗料-多樂士
import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;
/**
* 塗料 多樂士
*/
public class DuluxCoat implements Matter {
@Override
public String scene() {
return "塗料";
}
@Override
public String brand() {
return "多樂士";
}
@Override
public String model() {
return "第二代";
}
@Override
public BigDecimal price() {
return new BigDecimal(700);
}
@Override
public String desc() {
return "多樂⼠是阿克蘇諾⻉爾旗下的著名建築裝飾油漆品牌,產品暢銷於全球100個國\n" +
"家,每年全球有5000萬戶家庭使⽤多樂⼠油漆。";
}
}
塗料-立邦
import com.ustcinfo.strategy.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(600);
}
@Override
public String desc() {
return "⽴邦始終以開發綠⾊產品、注᯿⾼科技、⾼品質爲⽬標,以技術⼒量不斷推進科\n" +
"研和開發,滿⾜消費者需求。";
}
}
地板-德爾
import java.math.BigDecimal;
/**
* 地板 德爾
*/
public class DerFloor implements Matter {
@Override
public String scene() {
return "地板";
}
@Override
public String brand() {
return "德爾";
}
@Override
public String model() {
return "A+";
}
@Override
public BigDecimal price() {
return new BigDecimal(120);
}
@Override
public String desc() {
return "DER德爾集團是全球領先的專業⽊地板製造商,北京2008年奧運會家裝和公裝\n" +
"地板供應商";
}
}
地板-聖象
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(310);
}
@Override
public String desc() {
return "聖象地板是中國地板⾏業著名品牌。聖象地板擁有中國馳名商標、中國名牌、國\n" +
"家免檢、中國環境標誌認證等多項榮譽。";
}
}
地磚-東鵬
import com.ustcinfo.strategy.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年品牌\n" +
"價值132.35億元,位列建陶⾏業榜⾸。";
}
}
地磚-馬可波羅
package com.ustcinfo.strategy.tile;
import com.ustcinfo.strategy.Matter;
import java.math.BigDecimal;
/**
* 地磚 馬可波羅
*/
public class MarcoPoloTile implements Matter {
@Override
public String scene() {
return "地磚";
}
@Override
public String brand() {
return "馬可波羅";
}
@Override
public String model() {
return "缺省";
}
@Override
public BigDecimal price() {
return new BigDecimal(140);
}
@Override
public String desc() {
return "⻢可波羅品牌誕⽣於1996年,作爲國內最早品牌化的建陶品牌,以“⽂化陶\n" +
"瓷”佔領市場,享有“仿古磚⾄尊”的美譽。";
}
}
測試及運行結果
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class DecorationPackageController {
public static String decoration(BigDecimal area, Integer level) {
List<Matter> list = new ArrayList<Matter>(); // 裝修清單
BigDecimal price = BigDecimal.ZERO; // 裝修價格
// 豪華歐式
if (1 == level) {
LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊頂,⼆級頂
DuluxCoat duluxCoat = new DuluxCoat(); // 塗 料,多樂⼠
ShengXiangFloor shengXiangFloor = new ShengXiangFloor(); // 地板,聖象
list.add(levelTwoCeiling);
list.add(duluxCoat);
list.add(shengXiangFloor);
price = price.add(area.multiply(new
BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
price = price.add(area.multiply(new
BigDecimal("1.4")).multiply(duluxCoat.price()));
price = price.add(area.multiply(shengXiangFloor.price()));
}
// 輕奢⽥園
if (2 == level) {
LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊頂,⼆級頂
LiBangCoat liBangCoat = new LiBangCoat(); // 塗料,⽴邦
MarcoPoloTile marcoPoloTile = new MarcoPoloTile(); // 地磚,⻢可波羅
list.add(levelTwoCeiling);
list.add(liBangCoat);
list.add(marcoPoloTile);
price = price.add(area.multiply(new
BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
price = price.add(area.multiply(new
BigDecimal("1.4")).multiply(liBangCoat.price()));
price = price.add(area.multiply(marcoPoloTile.price()));
}
// 現代簡約
if (3 == level) {
LevelOneCeiling levelOneCeiling = new LevelOneCeiling(); //吊頂,⼆級頂
LiBangCoat liBangCoat = new LiBangCoat(); //塗料,⽴邦
DongPengTile dongPengTile = new DongPengTile(); //地磚,東鵬
list.add(levelOneCeiling);
list.add(liBangCoat);
list.add(dongPengTile);
price = price.add(area.multiply(new
BigDecimal("0.2")).multiply(levelOneCeiling.price()));
price = price.add(area.multiply(new
BigDecimal("1.4")).multiply(liBangCoat.price()));
price = price.add(area.multiply(dongPengTile.price()));
}
StringBuilder detail = new StringBuilder("\r\n-------------------------------------------------------\r\n" +
"裝修清單" + "\r\n" +
"套餐等級:" + level + "\r\n" +
"套餐價格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
"房屋⾯積:" + area.doubleValue() + " 平⽶\r\n" +
"材料清單:\r\n");
for(Matter matter:list) {
detail.append(matter.scene()).append(":")
.append(matter.brand()).append("、")
.append(matter.model()).append("、平⽶價格:")
.append(matter.price()).append(" 元。\n");
}
return detail.toString();
}
public static void main(String[] args) {
System.out.println(decoration(new BigDecimal(120.0), 1));
System.out.println(decoration(new BigDecimal(97.0), 2));
System.out.println(decoration(new BigDecimal(85.0), 3));
}
}
-------------------------------------------------------
裝修清單
套餐等級:1
套餐價格:174000.00 元
房屋⾯積:120.0 平⽶
材料清單:
吊頂:裝修公司自帶、二級頂、平⽶價格:800 元。
塗料:多樂士、第二代、平⽶價格:700 元。
地板:聖象、一級、平⽶價格:310 元。
-------------------------------------------------------
裝修清單
套餐等級:2
套餐價格:110580.00 元
房屋⾯積:97.0 平⽶
材料清單:
吊頂:裝修公司自帶、二級頂、平⽶價格:800 元。
塗料:立邦、默認級別、平⽶價格:600 元。
地磚:馬可波羅、缺省、平⽶價格:140 元。
-------------------------------------------------------
裝修清單
套餐等級:3
套餐價格:83470.00 元
房屋⾯積:85.0 平⽶
材料清單:
吊頂:裝修公司自帶、一級頂、平⽶價格:200 元。
塗料:立邦、默認級別、平⽶價格:600 元。
地磚:東鵬瓷磚、10001、平⽶價格:102 元。
建造者模式
IMenu
public interface IMenu {
/**
* 吊頂
* @param matter
* @return
*/
IMenu appendCeiling(Matter matter);
/**
* 塗料
* @param matter
* @return
*/
IMenu appendCoat(Matter matter);
/**
* 地板
* @param matter
* @return
*/
IMenu appendFloor(Matter matter);
/**
* 地磚
* @param matter
* @return
*/
IMenu appendTile(Matter matter);
/**
* 明細
* @return
*/
String getDetail();
}
DecorationPackageMenu
是 IMenu 接⼝的實現類,主要是承載建造過程中的填充器。相當於
這是⼀套承載物料和創建者中間銜接的內容。
public class DecorationPackageMenu implements IMenu {
// 裝修清單
private List<Matter> list = new ArrayList<Matter>();
// 裝修價格
private BigDecimal price = BigDecimal.ZERO;
/**
* ⾯積
*/
private BigDecimal area;
/**
* 裝修等級;豪華歐式、輕奢⽥園、現代簡約
*/
private String grade;
private DecorationPackageMenu() {
}
public DecorationPackageMenu(Double area, String grade) {
this.area = new BigDecimal(area);
this.grade = grade;
}
public IMenu appendCeiling(Matter matter) {
list.add(matter);
price = price.add(area.multiply(new
BigDecimal("0.2")).multiply(matter.price()));
return this;
}
public IMenu appendCoat(Matter matter) {
list.add(matter);
price = price.add(area.multiply(new
BigDecimal("1.4")).multiply(matter.price()));
return this;
}
public IMenu appendFloor(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
public IMenu appendTile(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
/**
* 明細
* @return
*/
public String getDetail() {
StringBuilder detail = new StringBuilder("\r\n-------------------- -----------------------------------\r\n" + "裝修清單" + "\r\n" + "套餐等級:" + grade + "\r\n" + "套餐價格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) +
" 元\r\n" + "房屋⾯積:" + area.doubleValue() + " 平⽶\r\n" + "材料清單:\r\n");
for (Matter matter: list) {
detail.append(matter.scene()).append(":").append(matter.brand()).append( "、").append(matter.model()).append("、平⽶價格:").append(matter.price()).append(" 元。\n");
}
return detail.toString();
}
}
Builder
建造者類具體的各種組裝由此類實現
public class Builder {
public IMenu levelOne(Double area) {
return new DecorationPackageMenu(area, "豪華歐式")
.appendCeiling(new LevelTwoCeiling()) // 吊頂,⼆級頂
.appendCoat(new DuluxCoat()) // 塗料,多樂⼠
.appendFloor(new ShengXiangFloor()); // 地板,聖象
}
public IMenu levelTwo(Double area){
return new DecorationPackageMenu(area, "輕奢⽥園")
.appendCeiling(new LevelTwoCeiling()) // 吊頂,⼆級頂
.appendCoat(new LiBangCoat()) // 塗料,⽴邦
.appendTile(new MarcoPoloTile()); // 地磚,⻢可波羅
}
public IMenu levelThree(Double area){
return new DecorationPackageMenu(area, "現代簡約")
.appendCeiling(new LevelOneCeiling()) // 吊頂,⼆級頂
.appendCoat(new LiBangCoat()) // 塗料,⽴邦
.appendTile(new DongPengTile()); // 地磚,東鵬
}
}
測試及測試結果
public class Test_Builder {
public static void main(String[] args) {
Builder builder = new Builder();
// 豪華歐式
System.out.println(builder.levelOne(132.52D).getDetail());
// 輕奢⽥園
System.out.println(builder.levelTwo(98.25D).getDetail());
// 現代簡約
System.out.println(builder.levelThree(85.43D).getDetail());
}
}
測試結果:
-------------------- -----------------------------------
裝修清單
套餐等級:豪華歐式
套餐價格:192154.00 元
房屋⾯積:132.52 平⽶
材料清單:
吊頂:裝修公司自帶、二級頂、平⽶價格:800 元。
塗料:多樂士、第二代、平⽶價格:700 元。
地板:聖象、一級、平⽶價格:310 元。
-------------------- -----------------------------------
裝修清單
套餐等級:輕奢⽥園
套餐價格:112005.00 元
房屋⾯積:98.25 平⽶
材料清單:
吊頂:裝修公司自帶、二級頂、平⽶價格:800 元。
塗料:立邦、默認級別、平⽶價格:600 元。
地磚:馬可波羅、缺省、平⽶價格:140 元。
-------------------- -----------------------------------
裝修清單
套餐等級:現代簡約
套餐價格:83892.26 元
房屋⾯積:85.43 平⽶
材料清單:
吊頂:裝修公司自帶、一級頂、平⽶價格:200 元。
塗料:立邦、默認級別、平⽶價格:600 元。
地磚:東鵬瓷磚、10001、平⽶價格:102 元。
總結: 當⼀些基本物料不會變,⽽其組合經常變化的時候 ,就可以選擇這樣的設計模式來構建代碼