zoukankan      html  css  js  c++  java
  • 三种构建器的使用

    平常开发中需要写很多domain类,bean等java类,每个类中可能需要写一些构造方法,但每次开发时时用到什么构造可能写下,偶尔会产生这样的想法,这些构造器的写法,能不能像工厂模式呀,或者其它设计模式一样,更通用一些,代码写的更优雅一些呢!巧的是,正好最近在看《Effective java》这边书,有个优化项正好时这个,所以这里参考下《Effective java》,总结下书中写,小记一下。

    多重叠构造器模式

    在我们平常的开发中,静态工厂模式,构造器等方法是我们常用的一种是自己代码“更优美”的写法。但写多后,不难发现它们都有一个共同的局限性--不能很好的扩展到大量的可选参数。举一个通俗一点的例子:我们平常炒一道菜,基本都会包含”油“,”盐“,”味精“常用的调料,有时依照不同的口味或者地区,我们可以再向菜中添加辣椒(喜欢吃辣的),糖(江浙沪这一带)。这时我们统计这些调味品时,油盐味精是必然的选项,都是有值的(每道菜含多少克),而辣椒,糖等调料就是可能值为0的。

    针对上面的调味品含量,写一个类,我可能就直接通过不同的构造器来写了,也就是多重叠构造器模式。如第一个构造器写一个全量参数,第二个构造器有一个可选项,第三个构造器有两个可选项,以此类推。。。

    
    public class Foot {
    
        private final int oil;
        private final int salt;
        private final int aginomoto;
    
        private final int chili;
        private final int sugar;
        
        public Foot(int oil, int salt, int aginomoto) {
            this(oil, salt, aginomoto, 0);
        }
    
        public Foot(int oil, int salt, int aginomoto, int chili) {
            this(oil, salt, aginomoto, chili, 0);
        }
    
        public Foot(int oil, int salt, int aginomoto, int chili, int sugar) {
            this.oil = oil;
            this.salt = salt;
            this.aginomoto = aginomoto;
            this.chili = chili;
            this.sugar = sugar;
        }
    
    }
    
    

    但要创建Foot的对象实例时,就利用参数列表中最短的构造器,但该构造器包含了要设置的所有参数。我们的本意是传我们所需要的参数,不需要的参数就不用传值了。我们Foot类有五个属性,所以使用起来并不是那么繁琐,但如果我们遇到很多属性时,根本无法用此方法写。《Effective java》书中说:“重叠构造器模式可行,但是当有许多参数时,客户端代码很难编写,并且仍然很难阅读“。当有很多参数的类型一样时,我们把参数值写乱,编译器并不会报错,程序运行时就会出现错误的行为。

    javaBeans模式

    这样我们就产生出第二种替代方法,javaBeans模式。我们通过一个无参构造来创建一个实例,然后通过set方法来给类中的属性赋值。

    
    public class Foot {
    
        private int oil;
        private int salt;
        private int aginomoto;
    
        private int chili;
        private int sugar;
    
        public void setOil(int oil) {
            this.oil = oil;
        }
    
        public void setSalt(int salt) {
            this.salt = salt;
        }
    
        public void setAginomoto(int aginomoto) {
            this.aginomoto = aginomoto;
        }
    
        public void setChili(int chili) {
            this.chili = chili;
        }
    
        public void setSugar(int sugar) {
            this.sugar = sugar;
        }
    }
    

    这种set方法弥补了重叠构造模式的不足。但缺点是:1构造过程被分到几个调用中,构造过程中的JavaBean可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。试图使用处于不一致的对象,将会导致失败,调试起来十分困难;2JavaBean模式阻止类把类做成不可变的困可能,需要程序员付出额外的努力来确保线程安全。

    Builder模式

    Builder模式可以保证安全性和可读性,拥有重叠模式和JavaBean模式的优点。Builder模式不直接生成想要的对象,而是让客户端利用必要的参数调用构造,得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数,最后通过build方法生成不可变的对象。

    
    public class Foot {
    
        private final int oil;
        private final int salt;
        private final int aginomoto;
        private final int chili;
        private final int sugar;
        
        private static class Builder {
            private int oil;
            private int salt;
            private int aginomoto;
    
            private int chili;
            private int sugar;
            
            public Builder(int oil, int salt, int aginomoto) {
                this.oil = oil;
                this.salt = salt;
                this.aginomoto = aginomoto;
            }
            
            public Builder chili(int param) {
                chili = param;
                return this;
            }
    
            public Builder sugar(int param) {
                sugar = param;
                return this;
            }
            
            public Foot build() {
                return new Foot(this);
            }
        }
        
        public Foot(Builder builder) {
            this.oil = builder.oil;
            this.salt = builder.salt;
            this.aginomoto = builder.aginomoto;
            this.chili = builder.chili;
            this.sugar = builder.sugar;
        }
        
    }
    

    创建对象:Foot foot = new Foot.Builder(1, 1, 1).chili(1).sugar(0).build();

    其中builder像个构造器一样,可以对其参数强加约束条件。与构造器相比,builder可以有多个可变的参数,它可以单独的设置每一个参数的值,可变参数有几个,它就可以设置几个。设置类参数的builder生成了一个很好的抽象工厂。

    Builder模式的不足,为了创建对象就必须创建它的构造器,也会有性能问题,它比重叠构造更加的冗长。所以它适合在更多的参数时使用。

    使用Builder模式的客户端代码会更容易阅读和维护编写,构建器也比JavaBeans更加安全。

  • 相关阅读:
    JavaScript借助xpath操纵xml数据(一)
    JavaScript借助xpath操纵xml数据(二)
    保留域——$$Return
    ExtJS中get、getDom、getCmp、getBody、getDoc使用 javascript
    关于编辑器编码保存为utf8问题
    query 用法
    简历模版(抛砖引玉)总觉得自己简历做得不够好的朋友请进来
    sql 查询慢的48个原因分析
    Word 实用技巧整理
    JAVA文件操作大全
  • 原文地址:https://www.cnblogs.com/levcon/p/9694098.html
Copyright © 2011-2022 走看看