在我們實際的開發需求中,經常需要建立同一型別的不同的物件,而且這個物件的特性還是隨機可變的,這樣就需要我們使用一種設計模式來滿足複雜多變的場景;我們以經常出現的喝咖啡為例,每種咖啡都有大杯小杯和中杯之分,然後咖啡可以新增糖、牛奶或者酒(?,這個口味就比較獨特了),我們可以搭配大杯咖啡+糖、大杯咖啡+牛奶、小杯咖啡+酒、大杯+糖+牛奶等等,隨著新增的種類的增多,搭配的種類也是不斷的呈指數級的變化的,那麼該如何使用**來建立這些搭配呢?
現在來介紹我們今天的主角builder,這裡的builder不是構建者模式,只是為了通過**的設計,來實現乙個方法鏈來實現物件的構建,下面通過一段**來簡單的介紹下builder的用法
我們先看看傳統的方式
public
class
coffee
那麼傳統的方式:
coffee coffee =
newcoffee()
; coffee.
setsize(1
);coffee.
setsugar
(boolean.true)
; coffee.
setmilk
(boolean.true)
; coffee.
setwine
(boolean.true)
;
這樣不是不可以 但是一旦我增加了新增的種類,改動的**就比較多了,而且,這樣的**也顯得比較low,沒有絲毫美感可言,所以我們這裡新增下靜態內部類來優化下:
public
class
coffee
public builder sugar
(boolean sugar)
public builder milk
(boolean milk)
public builder wine
(boolean wine)
public coffee builer()
}private
coffee
(builder builder)
public
intgetsize()
public
boolean
issugar()
public
boolean
ismilk()
public
boolean
iswine()
}
我們這裡新增了靜態內部類,其內部屬性我們這裡由於需求需要和父類的中的屬性是保持一致的,方便我們在內部類中來操作屬性物件的值,然後我們在內部類中提供方法來返回父類的物件,再接著,我們為了不讓父類來自己例項化物件,我們將父類的構造器私有化,避免父類通過構建在來建立物件;
這樣我們建立物件可以如下進行:
coffee coffee =
newcoffee.builder(1
).milk
(boolean.true)
.sugar
(boolean.true)
.builer()
;
這樣我們採用了鏈式的方式來建立物件,現在一看是不是很簡潔了,看著也很舒服了
設計來滿足上述需求
builder方法雖然方便了很多,但是並不能解決我們之前的需求,同時**量也是增大了很多,現在我們來使用一種設計方法來滿足該需求;
該怎麼去思考這個問題呢?
按照上面的思路我們來進行**開發:
public
abstract
class
coffee
/** * 定義個set集合來儲存新增種類
*/final set
categories;
/** * 定義乙個構建器 並且約束該構建器的型別
* 允許方法鏈在子類中執行正常,不需要進行型別強轉
** @param */
abstract
static
class
builder
coffee.builder
>
/** * 構建器,由子類去實現構建方法
** @return
*/abstract coffee build()
;/**
* 由子類來實現 返回子類的物件
** @return
*/protected
abstract t self()
;}/** * coffee 基類構造器
** @param builder
*/coffee
(coffee.builder<
?> builder)
}
上面我們定義了coffee基類,實現了我們之前思考的第一點,在基類中將需要新增的種類通過builder定義了新增子類的方法,那麼子類該如何定義呢?
public
class
sizecoffee
extends
coffee
private
final sizecoffee.size size;
/** * 定義靜態內部類來實現物件的建立
*/public
static
class
builder
extends
coffee.builder
/*** 返回子類物件
** @return
*/@override
coffee build()
@override
protected sizecoffee.builder self()
}/**
* largecoffee構造器
* 構造器私有化,為了防止通過父類來建立物件物件
** @param builder
*/private
sizecoffee
(builder builder)
}
這樣子類也建立好了,我們可以通過**來建立
coffee coffee =
newsizecoffee.builder
(sizecoffee.size.large)
.addcategories
(coffee.categorie.milk)
.addcategories
(coffee.categorie.sugar)
.build()
;
這樣的話,以後計算有什麼新增種類或者咖啡的包裝方式變換了,我們都可以基於該設計來實現我們的需求 VBA怎樣統計同一型別的資料的總和
今天是2014 11 01 是週末,忙了一周了,最終能夠閒下來了。想起近期工作用到的vba的乙個場景,結合vba的陣列,所以就想試試看。結果還好。出來了。這年頭,又玩起了vb了,經過多時才接受了vb的種語法風格,閒話不說,進入正題 比方如上的資料。我如今想統計出qqq所的總和是多少?ee的總和是多少...
labelme對同一型別的多個目標的識別問題
在使用labelme標記完影象後,我們可以使用labelme自帶的一套轉換工具 labelme json to dataset.exe 將每個對應的json檔案轉化為乙個字尾為 json的資料夾。資料夾內容如下 其中最重要的是名為label.png的16位,包含了具體哪乙個畫素作為mask的重要資訊...
C 學習(一)型別轉換
1.型別轉換按方式分為隱式轉換和顯式轉換。隱式轉換 由編譯器自動完成,無需使用者干預。顯式轉換 採用一定的形式進行轉換 型別名 資料 c中 型別名 資料 2.關於轉換建構函式 建構函式的一種,主要用於型別轉換,格式嚴格規定為單引數建構函式。例 complex類 complex double r in...