work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式-建造者

Posted on 2018-10-06 00:27  work hard work smart  阅读(192)  评论(0编辑  收藏  举报
 

一、定义

将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示

用户只需要指定需要建造的类型就可以得到它们,建造过程及细节不需要知道

类型:创建型

 

二、适用场景

如果一个对象有非常复杂的内部结构(很多属性)

想把复杂对象的创建和使用分离

 

三、优点

1、分装性好,创建和使用分离

2、扩展性好、建造类之间独立、一定程度上解耦

 

四、缺点

1、产生多余的Builder对象

2、产品内部发生变化,建造者都要修改,成本较大

 

五: Coding

1. 创建Course类

public class Course
{
    private String courseName;
    private String coursePPT;
    private String courseVideo;
    private String courseArticle;
    private String courseQA;

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getCoursePPT() {
        return coursePPT;
    }

    public void setCoursePPT(String coursePPT) {
        this.coursePPT = coursePPT;
    }

    public String getCourseVideo() {
        return courseVideo;
    }

    public void setCourseVideo(String courseVideo) {
        this.courseVideo = courseVideo;
    }

    public String getCourseArticle() {
        return courseArticle;
    }

    public void setCourseArticle(String courseArticle) {
        this.courseArticle = courseArticle;
    }

    public String getCourseQA() {
        return courseQA;
    }

    public void setCourseQA(String coureseQA) {
        this.courseQA = coureseQA;
    }

    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", coursePPT='" + coursePPT + '\'' +
                ", courseVideo='" + courseVideo + '\'' +
                ", courseArticle='" + courseArticle + '\'' +
                ", coureseQA='" + courseQA + '\'' +
                '}';
    }

  

 2. 创建CourseBuilder 抽象类

public abstract class CourseBuilder {

    public abstract  void buildCourseName(String courseName);
    public abstract  void buildCoursePPT(String coursePPT);
    public abstract  void buildCourseVideo(String courseVideo);
    public abstract  void buildCourseArticle(String courseArticle);
    public abstract  void buildCourseQA(String courseQA);
    public  abstract  Course makeCourse();
}

  

3. 创建CourseActualBuilder 类。 

public class CourseActualBuilder extends CourseBuilder {

    private  Course course = new Course();

    @Override
    public void buildCourseName(String courseName) {
        course.setCourseName(courseName);
    }

    @Override
    public void buildCoursePPT(String coursePPT) {
        course.setCoursePPT(coursePPT);
    }

    @Override
    public void buildCourseVideo(String courseVideo) {
        course.setCourseVideo(courseVideo);
    }

    @Override
    public void buildCourseArticle(String courseArticle) {
        course.setCourseArticle(courseArticle);
    }

    @Override
    public void buildCourseQA(String courseQA) {
        course.setCourseQA(courseQA);
    }

    @Override
    public Course makeCourse() {
        return course;
    }

  

4. 创建Coach类

public class Coach {
    private  CourseBuilder courseBuilder;

    public  void  setCourseBuilder(CourseBuilder courseBuilder){
        this.courseBuilder = courseBuilder;
    }

    public  Course makeCourse(String courseName, String coursePPT, String courseVideo,
                              String courseArticle, String courseQA){
        this.courseBuilder.buildCourseName(courseName);
        this.courseBuilder.buildCourseArticle(courseArticle);
        this.courseBuilder.buildCoursePPT(coursePPT);
        this.courseBuilder.buildCourseQA(courseQA);
        this.courseBuilder.buildCourseVideo(courseVideo);
        return this.courseBuilder.makeCourse();
    }
}

 

5. 创建测试类

public class Test {
    public static void main(String[] args) {
        Coach coach = new Coach();
        CourseBuilder courseBuilder = new CourseActualBuilder();
        coach.setCourseBuilder(courseBuilder);
        Course course = coach.makeCourse("Java","Java PPT","Video","Aritlce","QA 1");
        System.out.println(course);

    }
}

  

6. UML图

 

 

六:Coding 版本2(演进版)

1. 创建Course类

public class Course {
    private String courseName;
    private String coursePPT;
    private String courseVideo;
    private String courseArticle;
    private String courseQA;

    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", coursePPT='" + coursePPT + '\'' +
                ", courseVideo='" + courseVideo + '\'' +
                ", courseArticle='" + courseArticle + '\'' +
                ", courseQA='" + courseQA + '\'' +
                '}';
    }

    public Course(CourseBuilder courseBuilder){
        this.courseName = courseBuilder.courseName;
        this.courseArticle = courseBuilder.courseArticle;
        this.coursePPT = courseBuilder.coursePPT;
        this.courseQA = courseBuilder.courseQA;
        this.courseVideo = courseBuilder.courseVideo;
    }

    public static  class CourseBuilder{
        private String courseName;
        private String coursePPT;
        private String courseVideo;
        private String courseArticle;
        private String courseQA;

        public  CourseBuilder buildCourseName(String courseName){
            this.courseName = courseName;
            return  this;
        }

        public  CourseBuilder buildCoursePPT(String coursePPT){
            this.coursePPT = coursePPT;
            return  this;
        }

        public CourseBuilder buildCourseVideo(String courseVideo) {
            this.courseVideo = courseVideo;
            return  this;
        }


        public CourseBuilder buildCourseArticle(String courseArticle) {
            this.courseArticle = courseArticle;
            return  this;
        }


        public CourseBuilder buildCourseQA(String courseQA) {
            this.courseQA = courseQA;
            return  this;
        }

        public  Course build(){
            return  new Course(this);
        }
    }
}

  将构造器类CourseBuilder写成Course的内部类,并且CourseBuilder类如buildCourseName方法,实现链式编程。

 

2. 新建测试类

 

public class Test {
    public static void main(String[] args) {
        Course course = new Course.CourseBuilder().buildCourseName("Java课程").
                buildCourseArticle("文章").
                buildCourseVideo("视频").
                buildCoursePPT("PPT").build();
        System.out.println(course);
    }
}

  

3. UML图

 

七、构造者模式在源码中的使用

1. JDK中StringBuilder类

    public StringBuilder append(String var1) {
        super.append(var1);
        return this;
    }

  append方法,返回值是this

 

2. JDK中StringBuffer类

    public synchronized StringBuffer append(boolean var1) {
        super.append(var1);
        return this;
    }

  append方法,返回是this。 并且加了同步的方法synchronized。 所有StringBuffer是线程安全的。

 

3. guava中ImmutableSet

    public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements) {
        if(elements instanceof ImmutableSet && !(elements instanceof ImmutableSortedSet)) {
            ImmutableSet<E> set = (ImmutableSet)elements;
            if(!set.isPartialView()) {
                return set;
            }
        } else if(elements instanceof EnumSet) {
            return copyOfEnumSet((EnumSet)elements);
        }

        Object[] array = elements.toArray();
        return construct(array.length, array);
    }

  返回值是ImmutableSet。

ImmutableSet类中有一个内部类Builder,里面有一个add方法。类似于刚才改进版本Code(六:Coding 版本2(演进版))

 public static class Builder<E> extends ArrayBasedBuilder<E> {
        public Builder() {
            this(4);
        }

        Builder(int capacity) {
            super(capacity);
        }

        @CanIgnoreReturnValue
        public ImmutableSet.Builder<E> add(E element) {
            super.add(element);
            return this;
        }

        @CanIgnoreReturnValue
        public ImmutableSet.Builder<E> add(E... elements) {
            super.add(elements);
            return this;
        }

        @CanIgnoreReturnValue
        public ImmutableSet.Builder<E> addAll(Iterable<? extends E> elements) {
            super.addAll(elements);
            return this;
        }

        @CanIgnoreReturnValue
        public ImmutableSet.Builder<E> addAll(Iterator<? extends E> elements) {
            super.addAll(elements);
            return this;
        }

        public ImmutableSet<E> build() {
            ImmutableSet<E> result = ImmutableSet.construct(this.size, this.contents);
            this.size = result.size();
            return result;
        }
    }

  

ImmutableSet测试:
  Set<String> set = ImmutableSet.<String>builder().add("hello").add("world").build();
  System.out.println(set);

 

 

3. guava中CacheBuilder。

 

4. SpringMvc中的BeanDefinitionBuilder

    public static BeanDefinitionBuilder genericBeanDefinition() {
        BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
        builder.beanDefinition = new GenericBeanDefinition();
        return builder;
    }

  

5. Mybatis中的SqlSessionFactoryBuilder类

    public SqlSessionFactory build(Reader reader) {
        return this.build((Reader)reader, (String)null, (Properties)null);
    }

  返回SqlSessionFactory

 

解析Mybatis中的xml文件方法build。build方法中有XMLConfigBuilder,在建造者模式中再使用建造者。

 public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                reader.close();
            } catch (IOException var13) {
                ;
            }

        }

        return var5;
    }

  build是核心方法

    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }