Java常用設計模式————建造者模式
阿新 • • 發佈:2018-12-12
引言
建造者模式(Builder Pattern)使用多個簡單物件一步一步構建成一個複雜的物件。這種型別的設計模式屬於建造型模式,它提供了一種建立物件的最佳方式。
一個Builder會一步步構建最終的物件。該Builder類是獨立於其他物件的。
實現概要
建造者模式的實現並沒有一個特別經典的套路,原因是在多數情況下複雜物件的構建往往千奇百怪。但為了更好的理解建造者模式使用的場景,我們假設如下的功能需要:
因為建造者模式就是為了構建複雜物件,為了更加貼近這一點,以午餐(Meal)作為最終要被構建的物件,我們假設:午餐中分為食物(Item)和包裝(Packing)—>食物包含漢堡(Burger)
如果你看不懂上面的描述,或者已經準備關閉瀏覽器去做眼睛保健操,那麼下面的結構圖可能對你有所幫助:
實現過程
一、建立基礎介面
建立食物介面及具體實現類,建立包裝介面及具體包裝類:
public interface Item { /** 食物名稱*/ String name(); /** 包裝*/ Packing packing(); /** 總價*/ float price(); }
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
}
public class ChickenBurger extends Burger { @Override public String name() { return "Chicken Burger"; } @Override public float price() { return 50.5f; } }
public class VegBurger extends Burger {
@Override
public String name() {
return "Veg Burger";
}
@Override
public float price() {
return 25.0f;
}
}
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
}
public class Coke extends ColdDrink {
@Override
public String name() {
return "Coke";
}
@Override
public float price() {
return 30.0f;
}
}
public class Pepsi extends ColdDrink {
@Override
public String name() {
return "Pepsi";
}
@Override
public float price() {
return 35.0f;
}
}
public interface Packing {
String pack();
}
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
二、建立目標型別
此例中,目標型別即午餐類(Meal)
public class Meal {
private List<Item> items = new ArrayList<Item>();
public Meal addAll(List<? extends Item> items) {
this.items.addAll(items);
return this;
}
public Double getSum() {
return this.items.stream()
.collect(Collectors.summarizingDouble(Item::price))
.getSum();
}
public Double getAverage() {
return this.items.stream()
.collect(Collectors.summarizingDouble(Item::price))
.getAverage();
}
public void showItems() {
this.items.forEach(item -> {
System.out.print("Item : " + item.name());
System.out.print(", Packing : " + item.packing()
.pack());
System.out.println(", Price : " + item.price());
});
}
}
三、建立建造者類
public class MealBuilder {
public Meal prepareMeal(Item... items) {
return new Meal().addAll(Arrays.asList(items));
}
}
四、測試
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareMeal(new VegBurger(), new Coke());
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " + vegMeal.getSum());
Meal nonVegMeal = mealBuilder.prepareMeal(new ChickenBurger(), new Pepsi());
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " + nonVegMeal.getSum());
}
}
執行結果:
總結
意圖:建造者模式的用意就是將一個複雜的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示,例如本例中相同的建立午餐的方式,但使用不同的基礎物件,最終得出不一樣的套餐。
使用場景:一些基礎部件不會變,而其組合經常變化的時候。主要解決軟體系統中,有時候會面臨“一個複雜物件”的建立工作,其通常由多個子物件用一定的演算法構成。由於需求的變化,這個複雜物件的各個部件經常面臨著劇烈的變化,但將它們組合在一起的演算法相對穩定。
優點:建造者獨立,易擴充套件;便於控制細節風險。
缺點:產品必須有共同點,範圍有限制;內部變化複雜,會有很多建造類。
鳴謝
《建造者模式》