Kiven 每天都需要有所獲,每天都需要進步.........
前言
建造者模式在設計模式中還算是一個用的比較多的設計模式,建造者設計模式的核心在於隱藏內部構建細節,通過外部的Builder來實現構建。Builder負責Product類物件的具體過程構建,Director負責指導Build,要求Builder按照其指定的順序去完成Produt的構造。最後通過Builder返回建造後的結果。
標準建造者模式
/**
* 建造者角色
* 工人介面,定義了各個工人所需要進行的工作
* 並不負責具體的建造
*
* 同時房子是具體的(農民工)建造的 所以需要有返回房子的方法
* @author tucheng
*
*/
public interface Build {
public void makeWindow();
public void makeFloor();
public Room getRoom();
}
public class WorkBuilder implements Build{
private Room room=new Room();
@Override
public void makeWindow() {
room.setFloor("地板 ");
}
@Override
public void makeFloor() {
room.setWindow("窗戶");
}
@Override
public Room getRoom() {
return room;
}
}
/**
* 房子類
* 首先要描述下 房子要有些什麼
* 有哪些屬性
*
* @author tucheng
*
*/
public class Room {
private String window;
private String floor;
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "---->floor "+floor+" window "+window;
}
}
/**
* 指導者 角色
* 所具備的能力
*
* 設計師 他知道房子怎麼設計
* 他會指揮工人去建造
* 實際生活中 大廈的設計者並不會看大廈的具體實現細節
* 更多的是從整體角度出發,指揮這個工人團隊建造
* 所以他肯定對工人所具備的能力和行為有很深的瞭解
* 換做程式程式碼中 ,他也肯定會持有工人 的這個物件的引用
*
*
* @author tucheng
*
*/
public class Designer {
public void order(Build build)
{
build.makeFloor();
build.makeWindow();
}
}
public class Client {
public static void main(String[] args) {
Build worker = new WorkBuilder(); //獲取工人物件
Designer designer = new Designer(); //獲取設計師物件
designer.order(worker); //設計師指揮工人工作
System.out.println(worker.getRoom());; //工人交房
}
}
上面就是一個標準的建造者模式,有設計者、有建造者,但是不覺會發現設計師屬於多餘的一個角色,接著看下對它進行的優化.
優化建造者模式
public class WorkBuilder{
private RoomParmas parmas;
public WorkBuilder( ) {
this.parmas = new RoomParmas();
}
public WorkBuilder makeWindow(String window ) {
parmas.window=window;
return this;
}
public WorkBuilder makeFloor(String floorCorlor) {
parmas.floor=floorCorlor;
return this;
}
public WorkBuilder makeDoor(String door) {
parmas.door=door;
return this;
}
public Room makeChat(String chat) {
parmas.chat=chat;
Room room=new Room();
return room;
}
public void show()
{
}
public Room build() {
Room room=new Room();
room.apply(parmas);
return room;
}
class RoomParmas
{
public String window;
public String floor;
public String door;
public String chat;
}
}
/**
* 房子類
* 首先要描述下 房子要有些什麼
* 有哪些屬性
*
* @author tucheng
*
*/
public class Room {
private String window;
private String floor;
private String doorl;
private String chat;
public void apply(WorkBuilder.RoomParmas parmas)
{
window=parmas.window;
floor=parmas.floor;
doorl=parmas.door;
chat=parmas.chat;
}
public void setChat(String chat) {
this.chat = chat;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "---->floor "+floor+" window "+window;
}
public void show()
{
}
}
public class Client {
public static void main(String[] args) {
Room room=(new WorkBuilder()).makeWindow("藍色玻璃").makeFloor("黃色地板").makeChat("").show();; //獲取工人物件
System.out.println(room);; //工人交房
}
}
看到上面的鏈式呼叫相信很多人就豁然開朗,這不就是類似於三方框架glide、imageloader的鏈式呼叫嘛,說的沒錯,之所以說建造者模式常用,用的最多的就是存在與三方框架,因為三方框架中包含的實現細節比較多,所以為了不給外部看到內部的實現細節,同時又能給使用者更好的擴充套件,程式碼又整潔,只有通過這種方式才能實現此目的。
責任鏈模式
責任鏈模式是一種設計模式。在責任鏈模式裡,很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個物件最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。
責任鏈模式涉及到的角色如下所示:
● 抽象處理者(Handler)角色:定義出一個處理請求的介面。如果需要,介面可以定義 出一個方法以設定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java介面實現。上圖中Handler類的聚合關係給出了具體子類對下家的引用,抽象方法handleRequest()規範了子類處理請求的操作。
● 具體處理者(ConcreteHandler)角色:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。
實現方式:
public abstract class Handler {
public Handler nextHandler;
public void handleRequest(AbstractRequest abstractRequest)
{
if(getHandleLevel()==abstractRequest.getRequestLevel())
{
handle(abstractRequest);
}else {
if(nextHandler!=null)
{
nextHandler.handleRequest(abstractRequest);
}else {
System.out.println("----> 所有的處理物件都不能處理它");
}
}
}
/**
* 每個處理者的物件的具體處理方式
* @param abstractRequest
*/
public abstract void handle(AbstractRequest abstractRequest);
/**
* 每個處著物件處理的級別
* @return
*/
public abstract int getHandleLevel();
}
public class Handler1 extends Handler{
@Override
public void handle(AbstractRequest abstractRequest) {
System.out.println("----handle1 處理請求: "+abstractRequest.getRequestLevel());
}
@Override
public int getHandleLevel() {
return 1;
}
}
public class Handler2 extends Handler {
@Override
public void handle(AbstractRequest abstractRequest) {
System.out.println("----handle2 處理請求: "+abstractRequest.getRequestLevel());
}
@Override
public int getHandleLevel() {
return 2;
}
}
public class Handler3 extends Handler {
@Override
public void handle(AbstractRequest abstractRequest) {
System.out.println("----handle3 處理請求: "+abstractRequest.getRequestLevel());
}
@Override
public int getHandleLevel() {
return 3;
}
}
public abstract class AbstractRequest {
private Object object;
public AbstractRequest(Object object)
{
this.object=object;
}
/**
* 具體的內容物件
* @return
*/
public Object getContent()
{
return object;
}
/**
* 獲取請求級別
*/
public abstract int getRequestLevel();
}
public class Request1 extends AbstractRequest{
public Request1(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest{
public Request2(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 2;
}
}
public class Request3 extends AbstractRequest{
public Request3(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 3;
}
}
public class Client {
public static void main(String[] args) {
//確定鏈式關係
Handler handler1=new Handler1();
Handler handler2=new Handler2();
Handler handler3=new Handler3();
handler1.nextHandler=handler2;
handler2.nextHandler=handler3;
AbstractRequest request3=new Request3("請求1");
handler1.handleRequest(request3);
}
}
責任鏈模式需要發生者去手動建立關係,當遇到if-else比較多的場景的時候,很多的if-else會導致程式碼不美觀,而且擴充套件性不好。