设计模式---Builder模式

1.什么是builder模式

   简单解释,在程序设计的时候,如果面对的对象属性较多,对象复杂性比较大(例如对象包含对象)的情况,开发者选择这种设计模式去设计一个类的时候,开发者可以在不知道类内部结构构建细节的情况下,清晰地控制对象构造流程。例如,一个person类拥有很多属性的时候,最常见的比如name,age,weight,height等等。在这里两个地方体现出builder模式的优势:

(1)如果在创建一个person对象,只需要name、age属性,则需要创建多一个包含这两个属性的构造方法。需求不一样,构造方法就需要更多。累赘。
(2)对于普通的构造方法,当我们初始化weight、height两个属性的时候,我们一般会如下。

Person person = new Person("123","53");

如果属性一多,我们根本很模糊知道weight是哪个。

2.模式适用范围

(1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
(2)当构造过程必须允许被构造的对象有不同的表示时。
(3)Builder模式要解决的也正是这样的问题:
  当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),
  我们要复杂对象的创建过程和这个对象的表示(展示)分离开来,
  这样做的好处就是通过一步步的进行复杂对象的构建,
  由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

3.具体应用

笔者这里通过汽车Car类对象包含引擎Engine类、导航Naviaror类、车轮Wheel类作为一个复杂性类说明Builder模式的应用。

(1)公有抽象类Car

 
/**
 * 车的抽象类 较复杂的对象,对象包含对象
 * Created by wsy on 2016/2/17.
 */
public abstract class Car {
 
    protected Engine mEngine;
    protected Navigator mNavigator;
    protected Wheel mWheel;
 
    public Car() {
    }
 
    public Car(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
        this.mEngine = mEngine;
        this.mNavigator = mNavigator;
        this.mWheel = mWheel;
    }
 
    /**
    public Car(Engine mEngine) {
        this.mEngine = mEngine;
    }
 
    public Car(Engine mEngine, Navigator mNavigator) {
        this.mEngine = mEngine;
        this.mNavigator = mNavigator;
    }
     **/
 
    public Engine getmEngine() {
        return mEngine;
    }
 
    public void setmEngine(Engine mEngine) {
        this.mEngine = mEngine;
    }
 
    public Navigator getmNavigator() {
        return mNavigator;
    }
 
    public void setmNavigator(Navigator mNavigator) {
        this.mNavigator = mNavigator;
    }
 
    public Wheel getmWheel() {
        return mWheel;
    }
 
    public void setmWheel(Wheel mWheel) {
        this.mWheel = mWheel;
    }
 
    @Override
    public String toString() {
        return "Car{" +
                "mEngine=" + mEngine +
                ", mNavigator=" + mNavigator +
                ", mWheel=" + mWheel +
                '}';
    }
}

(2) 具体实现奔驰类

/**
 * 奔驰实体类
 * Created by wsy on 2016/2/17.
 */
public class BenzCar extends Car {
 
    public BenzCar() {
    }
 
    public BenzCar(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
        super(mEngine, mNavigator, mWheel);
    }
 
    /**
    public BenzCar(Engine mEngine) {
        super(mEngine);
    }
 
    public BenzCar(Engine mEngine, Navigator mNavigator) {
        super(mEngine, mNavigator);
    }
     **/
 
    // 这里如果重写了,直接通过this.mEngine,因为是父类projected类型,访问不到,因此日志打印会为空值,多态
//    @Override
//    public void setmEngine(String mEngine) {
//        mEngine = "Benz Engine 2016";
//    }
}

(3)Car车构建类Builder

/**
 * 奔驰构建类
 * Created by wsy on 2016/2/17.
 */
public class BenzBuilder{
 
    private Car mCar = new BenzCar();
 
    public BenzBuilder builderEngine(Engine mEngine) {
        mCar.setmEngine(mEngine);
        return this;
    }
 
    public BenzBuilder builderWheel(Wheel mWheel) {
        mCar.setmWheel(mWheel);
        return this;
    }
 
    @Override
    public Builder builderNavigator(Navigator mNavigator) {
        mCar.setmNavigator(mNavigator);
        return this;
    }
 
    public Car onCreate() {
        return mCar;
    }
}

(4)引擎Engine类、导航Naviaror类、车轮Wheel类(这里构建类builder都是静态内部类)

/**
 * 引擎实体类
 * Created by wsy on 2016/2/17.
 */
public class Engine {
 
    private String brand;
    private String power;
 
    public Engine(String brand, String power) {
        this.brand = brand;
        this.power = power;
    }
 
    public Engine() {
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getPower() {
        return power;
    }
 
    public void setPower(String power) {
        this.power = power;
    }
 
    @Override
    public String toString() {
        return "Engine{" +
                "brand='" + brand + '\'' +
                ", power='" + power + '\'' +
                '}';
    }
 
    public static class EngineBuilder{
 
        private Engine mEngine = new Engine();
        private String brand;
        private String power;
 
        public EngineBuilder setBrand(String brand) {
            mEngine.setBrand(brand);
          return this;
        }
 
        public EngineBuilder setPower(String power) {
            mEngine.setPower(power);
            return this;
        }
 
        public Engine create(){
            return mEngine;
        }
 
    }
 
}
package cn.wsy.builder.simple.common;
 
/**
 * 导航仪实体类
 * Created by wsy on 2016/2/17.
 */
public class Navigator {
 
    private String brand;
    private String price;
 
    public Navigator(String brand, String price) {
        this.brand = brand;
        this.price = price;
    }
 
    public Navigator() {
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getPrice() {
        return price;
    }
 
    public void setPrice(String price) {
        this.price = price;
    }
 
    @Override
    public String toString() {
        return "Navigator{" +
                "brand='" + brand + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
 
    public static class NavigatorBuilder {
        private Navigator mNavigator = new Navigator();
        private String brand;
        private String price;
 
        public NavigatorBuilder setPrice(String price) {
            mNavigator.setPrice(price);
            return this;
        }
 
        public NavigatorBuilder setBrand(String brand) {
            mNavigator.setBrand(brand);
            return this;
        }
 
        public Navigator create(){
            return mNavigator;
        }
 
    }
 
}
package cn.wsy.builder.simple.common;
 
/**
 * 车轮实体类
 * Created by wsy on 2016/2/17.
 */
public class Wheel {
 
    private String brand;
    private String weight;
 
    public Wheel() {
    }
 
    public Wheel(String brand, String weight) {
        this.brand = brand;
        this.weight = weight;
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getWeight() {
        return weight;
    }
 
    public void setWeight(String weight) {
        this.weight = weight;
    }
 
    @Override
    public String toString() {
        return "Wheel{" +
                "brand='" + brand + '\'' +
                ", weight='" + weight + '\'' +
                '}';
    }
 
    public static class WheelBuilder{
        private Wheel mWhell = new Wheel();
        private String brand;
        private String weight;
 
        public WheelBuilder setBrand(String brand) {
            mWhell.setBrand(brand);
           return this;
        }
 
        public WheelBuilder setWeight(String weight) {
            mWhell.setWeight(weight);
            return this;
        }
 
        public Wheel create(){
            return mWhell;
        }
    }
}

(4)测试方法
这里我们通过对比传统构造方法来对比Builder构造的优势:
1.如果类奔驰车类构造对象的时候不需要导航仪类,传统的构造方法需要定义多一个构造方法,具体如下:

 public BenzCar(Engine mEngine, Wheel mWheel) {
           super(mEngine, mWheel);
 }

构造如下:

BenzCar car1 = new BenzCar(new Engine("321","321"),new Wheel("123","123"));

2.利用builder模式构造

//这种方式创建 可观性清晰 构造器也可以减少
BenzBuilder builder = new BenzBuilder();//oncreate 可以拿到实体对象
BenzCar car = (BenzCar) builder
                       .builderEngine(new Engine.EngineBuilder().setBrand("brand").create())
                       .builderNavigator(new Navigator.NavigatorBuilder().setPrice("price").create()) 
                       .onCreate()
                      ;Log.i(TAG, car.toString());

这样是不是更加清晰!需求改动、最初类属性没有修改的时候,可以直接不用修改类的构造方法,维护性更高!但是这种方式会严重增加的代码量,所以各有优缺点!!

傻小孩b
20160217

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 上一篇文章设计模式-单例模式我们介绍了单例模式的几种用法和优缺点,具体的我们需要结合项目中的场景去具体选择。这一篇...
    i卓阅读 323评论 0 1
  • Builder模式可以称为建造者模式,它将一个复杂对象的构建和表示分离,同样的构建过程可以创建不同的表示 适用场景...
    KevinLive阅读 649评论 0 0
  • 模式的定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 模式的使用场景 相同的方法...
    狠哇塞的小伙子啊阅读 348评论 0 1
  • Builder模式 定义:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。 使用场景:(...
    ping_平阅读 292评论 0 2
  • Retrofit中的Builder模式 1、Retrofit的构造 以上是Retrofit的构造过程(其实在Bui...
    gzfgeh阅读 541评论 0 0