zoukankan      html  css  js  c++  java
  • 设计模式01-----builder设计模式

    最近开发任务中碰到一个非常好用的模式,那就是builder设计模式(即建造者设计模式)。

    说到builder设计模式,常常会跟可重叠构造器和javabeans模式一起比较说明。下面分别讨论:

    一. 可重叠构造器模式

    可重叠构造器的意思就是有很多的构造器,只是参数个数,参数类型不一样。举个到处都在用的例子把:

    package com.test.b;
    
    public class Person {
        //必要参数
        private int id;
        private String name;
        //可选参数
        private int age;
        private String sex;
        private String phone;
        public Person(int id,String name) {
            this(id,name,0);
        }
        
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", phone=" + phone + "]";
        }
    
        public Person(int id,String name,int age) {
            this(id, name,age,"");
        }
    
        public Person(int id, String name, int age, String sex) {
            this(id, name,0,"","");
        }
        
        public Person(int id,String name,int age,String sex,String phone) {
            this.id=id;
            this.name=name;
            this.age=age;
            this.sex=sex;
            this.phone=phone;
        }
    
        
    }

    虽然测试的时候,只传入了name和id就可以拿到对象,但是最终打印出来的确是很多参数的一个Person。很多参数的值还不符合常理,需要我们去处理。因此并不方便。这样的话,我们又不得不传入更多的参数,可是,我们只想用name和id两个参数。当然,也可以不用this,就写很多的构造器,但是参数个数不同而带来的构造器个数不同,者会导致太多的构造器,不好区分。有些参数都是string,还容易传错值,易混淆。

    二. javabeans模式

    package com.test.b;
    
    import java.io.Serializable;
    
    public class Person implements Serializable{
        
        //必要参数
        private  int id;
        private  String name;
        //可选参数
        private  int age;
        private  String sex;
        private  String phone;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
        
    
        
    }

    对于程序可读性以及参数的可控性的考虑我们会是会用javabean来进行类实例化和属性的赋值。

    在使用javabean的时候,尤其是多线程时候,获取同一个javabean(可以通过序列/反序列获取),那么下面模拟一个场景:
    线程A: 获取person,对其name age sex 就行set操作
    同样线程B: 获取person,对其进行get操作
    这时候会出现一种情况,在线程A中没有set完毕,线程B 就开始取相应的属性

    三. builder设计模式

    package com.test.b;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
    
        // 必要参数
        private int id;
        private String name;
        // 可选参数
        private int age;
        private String sex;
        private String phone;
    
        public Person(Builder builder) {
            this.id = builder.id;
            this.name = builder.name;
            this.age = builder.age;
            this.sex = builder.sex;
            this.phone = builder.phone;
    
        }
    
        public int getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getSex() {
            return sex;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public static class Builder {
            private int id;
            private String name;
            private int age;
            private String sex;
            private String phone;
    
            public Builder setId(int id) {
                this.id = id;
                return this;
            }
    
            public Builder setName(String name) {
                this.name = name;
                return this;
            }
    
            public Builder setAge(int age) {
                this.age = age;
                return this;
            }
    
            public Builder setSex(String sex) {
                this.sex = sex;
                return this;
            }
    
            public Builder setPhone(String phone) {
                this.phone = phone;
                return this;
            }
    
            public Person build() {
                return new Person(this);
            }
        }
    }

    NOTE:最终使用的时候 Person person=new Person.Builder().set....().build()方式来得到person对象

    在建造者模式中,提供一个辅助的静态建造器builder,可以在里面set Person的属性,与javaBean不同的是,建造者是先set,在通过build实例化person,这样既可以提高代码的阅读性,也可以防止对象没有实例化,就被调用;不会造成不一致性,同时解决了javabean模式的线程安全问题;

    四. 比较

    重叠构造器模式 形式简单 容易出错,参数表太长不容易控制,而且难以阅读
    javaBean模式 容易阅读,创建实例比较容易 构造过程被分割到好多个set中容易造成线程不安全,导致对象处于不一致的状态
    Builder模式 代码容易编写 创建对象,必须先创造构建器,造成一定的性能上的开销



  • 相关阅读:
    ActionResult 的返回类型
    MVC4.0中ViewBag、ViewData、TempData和ViewModel几种传值方式的区别
    抛出异常的区别 throw 和throw ex
    字段的重复校验问题
    bootstrap 动态添加验证项和取消验证项
    VS快捷键大全(转)
    数组、List和ArrayList的区别
    处理两个泛型集合差异化
    传参的两种方式
    tomcat中web项目编译后的结构
  • 原文地址:https://www.cnblogs.com/Hermioner/p/9962750.html
Copyright © 2011-2022 走看看