美文网首页
Builder 模式

Builder 模式

作者: Jacky_1bbe | 来源:发表于2018-03-16 11:43 被阅读0次

    Builder 模式

    引入

    这个设计模式有什么用,解决什么问题,为什么要用

    • 一个类有很多的field,构造函数很复杂
    • 处理对象的不可变性

    例子

    • StringBuilder
    • DocumentBuiler
    • Locale.Builder

    详解

    例1

    现有一个“订餐类”LunchOrderBean,其中有属性面包,调料,肉等等属性

    实现一:默认构造函数和setter方法
    public class LunchOrderBean {
    
        private String bread;
        private String condiments;
        private String dressing;
        private String meat;
    
        public LunchOrderBean() {
    
        }
    
        public String getBread() {
            return bread;
        }
    
        public String getCondiments() {
            return condiments;
        }
    
        public String getDressing() {
            return dressing;
        }
    
        public String getMeat() {
            return meat;
        }
    
        public void setBread(String bread) {
            this.bread = bread;
        }
    
        public void setCondiments(String condiments) {
            this.condiments = condiments;
        }
    
        public void setDressing(String dressing) {
            this.dressing = dressing;
        }
    
        public void setMeat(String meat) {
            this.meat = meat;
        }
    
    }
    

    我们要使用这个类,也就是获取这个类的对象,如何做?
    很简单,就像下面这样

            LunchOrderBean lunchOrderBean = new LunchOrderBean();
    
            lunchOrderBean.setBread("Wheat");
            lunchOrderBean.setCondiments("Lettuce");
            lunchOrderBean.setDressing("Mustard");
            lunchOrderBean.setMeat("Ham");
    
            System.out.println(lunchOrderBean.getBread());
            System.out.println(lunchOrderBean.getCondiments());
            System.out.println(lunchOrderBean.getDressing());
            System.out.println(lunchOrderBean.getMeat());
    

    我们看到这个类有一个默认的无参数的构造函数,且对每个属性都有setter方法。
    但是这样的问题是:

    1. 类LunchOrderBean不是不可变的(immutable),这意味着在创建它的对象后,我们可以通过setter方法来改变对象的状态
    2. 从类本身看不出类的使用规范或说明,也就是说我们看不出对一个合法的order来说,哪些属性是必须的,哪些是可选的。
    实现二 层叠(telescoping)构造函数
    public class LunchOrderTele {
    
        private String bread;
        private String condiments;
        private String dressing;
        private String meat;
    
        public LunchOrderTele(String bread) {
            this.bread = bread;
        }
    
        public LunchOrderTele(String bread, String condiments) {
            this(bread);
            this.condiments = condiments;
        }
    
        public LunchOrderTele(String bread, String condiments, String dressing) {
            this(bread, condiments);
            this.dressing = dressing;
        }
    
        public LunchOrderTele(String bread, String condiments, String dressing, String meat) {
            this(bread, condiments, dressing);
            this.meat = meat;
        }
    
        public String getBread() {
            return bread;
        }
    
        public String getCondiments() {
            return condiments;
        }
    
        public String getDressing() {
            return dressing;
        }
    
        public String getMeat() {
            return meat;
        }
    }
    

    这个实现消除了setter方法,解决了“不可变”的问题。
    并且使用了很多构造函数,我们称为层叠(telescoping)构造函数,让我们可以创建我们想要的order,只有面包的,有面包和调料的,有面包和调料和肉的等等。
    但是它没有列举出所有情况,假如我们想要一个只有面包和肉的,它就无能为力了。

    实现三 builder模式
    public class LunchOrder {
    
        public static class Builder {
            private String bread;
            private String condiments;
            private String dressing;
            private String meat;
            
            public Builder() {
                
            }
            
            public LunchOrder build() {
                return new LunchOrder(this);
            }
            
            public Builder bread(String bread) {
                this.bread = bread;
                return this;
            }
            
            public Builder condiments(String condiments) {
                this.condiments = condiments;
                return this;
            }
            
            public Builder dressing(String dressing) {
                this.dressing = dressing;
                return this;
            }
            
            public Builder meat(String meat) {
                this.meat = meat;
                return this;
            } 
            
        }
        
        private final String bread;
        private final String condiments;
        private final String dressing;
        private final String meat;
    
        private LunchOrder(Builder builder) {
            this.bread = builder.bread;
            this.condiments = builder.condiments;
            this.dressing = builder.dressing;
            this.meat = builder.meat;
        }
    
        public String getBread() {
            return bread;
        }
    
        public String getCondiments() {
            return condiments;
        }
        
        public String getDressing() {
            return dressing;
        }
        
        public String getMeat() {
            return meat;
        }
        
    }
    

    相关文章

      网友评论

          本文标题:Builder 模式

          本文链接:https://www.haomeiwen.com/subject/fdrlqftx.html