Java设计模式——Builder模式
前言
? 之前寫Android程序的時候,經常會用到Dialog(對話框)這個控件。我們在使用Dialog,比如AlertDialog的時候就用到了這里要說明的Builder模式。現在我們來看一下這樣的一段代碼:
public void showDialog() {Builder builder = new AlertDialog.Builder(this);AlertDialog dialog = builder.setIcon(R.drawable.ic_launcher).setMessage("Hello Boy.").create();dialog.show();} ? 我們可以通過這種方式來顯示一個系統自帶的對話框。不知道大家有沒有想過為什么Dialog要通過這種方式來構建呢?直接new出來不是更直接么?下面就通過Builder模式來詳細說明一下這個問題。版權說明
著作權歸作者所有。
商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
作者:Coding-Naga
發表日期: 2015年12月11日
鏈接:http://blog.csdn.net/lemon_tree12138/article/details/50246499
來源:CSDN
更多內容:分類 >> 設計模式
?
定義
? builder模式的使用目的是為了將構建復雜對象的過程和它的部件解耦。將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
說明
? 要怎么理解上面概述的這句話呢?在上一篇《Java設計模式——工廠模式》博客中,我們知道了,如果一個類比較復雜,我們在new這個對象的時候就要多個心眼了。為什么?因為我們要考慮程序部件之間的耦合度。當然,我們也可以使用上篇的工廠模式來解決,不過這不屬于我們本篇博客的范圍。
? 既然說到了對象的構建過程和部件需要解耦,那么勢必會有兩個不同的類,分別是構建過程類和部件類。我們可以從下面的圖-2中看到這一點,分別是兩個接口:HeroBuilder和Hero。下面就來列舉一個實例加以說明。
圖-1 簡單Builder模式
圖-2 Builder模式類圖
實例及過程說明
背景
? 因為博主是一個DotAer,所以這里我就列舉創建一個DotA英雄的過程吧。(真實游戲中英雄的創建并不是這樣的,你可以理解這是一個外掛程序-_-!)。
? 每一個英雄在被創建之前,他們都有一個抽象的統稱——Hero。這里定義成一個接口。
? 每一個英雄都有以下屬性:玩家id、當前等級、當前學習技能點、當前裝備。
創建過程
? 這里我定義一個HeroBuilder的來抽象創建英雄,讓具體的創建者TraxexBuilder去實現抽象創建者。所以,真實創建的時候,是通過具體創建者來實現的。我們把具體英雄的創建交給了一個創建者,這一點是不是跟工廠模式中的使用工廠來生產產品很類似?
創建者接口
? 首先,我們定義一個接口來告訴具體的創建者要如何創建復雜對象的組件。
public interface HeroBuilder {public HeroBuilder userName(String _name);public HeroBuilder level(Level _level);public HeroBuilder skills(List<Skill> _skills);public HeroBuilder equipments(List<Equipment> _equipments); }
具體創建者
? 具體的創建者要實現創建者接口,然后提供一個能夠返回對象的接口。public class TraxexBuilder implements HeroBuilder {private Traxex traxex;public String userName; // 玩家idpublic Level level; // 玩家等級public List<Skill> skills; // 學習技能點public List<Equipment> equipments; // 當前裝備@Overridepublic HeroBuilder userName(String _name) {userName = _name;return this;}... ...public Traxex build() {if (traxex == null) {traxex = new Traxex(this);}return traxex;} }
對象的接口
? 這里我們為英雄統一定義一個接口,用于規定好英雄需要做哪些事情。這些事情到時候就交給創建者來完成。public interface Hero {public void setUserName(String name);public void setLevel(Level level);public void setSkill(List<Skill> skills);public void setEquipment(List<Equipment> equipments);}
具體的對象實例
? 這里為了方便說明更理解,下面的具體對象中省略了很多內容。完整的代碼可以在下面的GitHub鏈接中下載。public class Traxex implements Hero {private String userName; // 玩家idprivate Level level; // 玩家等級private List<Skill> skills; // 學習技能點private List<Equipment> equipments; // 當前裝備// 省略從Hero接口中重寫的方法// 省略自定義方法public Traxex(TraxexBuilder _builder) {// 省略完成從創建者那里獲得的屬性信息}@Overridepublic String toString() {... ...return something;} }
組裝
? 有了以上的這幾個部分,事情大體完成了。說是大體完成的原因是因為還有最一步了,那就是組裝(Director)。? 你是不是要問我,為什么之前有了一個Builder是具體創建者了,這里還要有一個Director,這是什么鬼?先別急,讓我們來了解一下Builder和Director的區別,之后你就好理解了。
? 從上面的代碼和分析中,我知道了Builder是一個創建者,它負責的是創建復雜對象中的各個組件。比如例子中的英雄等級、學習技能、合成的裝備等。那么我們創建好了這些單個組件之后,是不是應該把這些組件組裝到具體的對象上呢?答案是肯定的。那么這里的Director就是干這個事情的啦。請看下面的代碼:
public class Director {private HeroBuilder builder = null;public Director(HeroBuilder _builder) {builder = _builder;}public void construct(String _playerName, Level _level, List<Skill> _skills, List<Equipment> _equipments) {builder.userName(_playerName).level(_level).skills(_skills).equipments(_equipments);} }
客戶端測試
public class BuilderClient {public static void main(String[] args) {// 技能定義List<Skill> skills = getSkills();// 裝備定義List<Equipment> equipments = getEquipments();// 構建對象TraxexBuilder builder = new TraxexBuilder();Director director = new Director(builder);director.construct("Naga007", Level.Level_19, skills, equipments);Traxex traxex = builder.build();System.out.println(traxex);}... ... }測試結果
圖-3 程序運行結果
GitHub源碼鏈接
https://github.com/William-Hai/DesignPattern-Builder
總結
以上是生活随笔為你收集整理的Java设计模式——Builder模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式——工厂模式
- 下一篇: 数据结构:二叉搜索树(BST)的基本操作