• 07、Java模式建造者模式


    建造者模式

    将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。

    该模式的主要优点如下:

    1. 封装性好,构建和表示分离。
    2. 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
    3. 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

    其缺点如下:

    1. 产品的组成部分必须相同,这限制了其使用范围。
    2. 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

    建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。

    模式的结构

    建造者(Builder)模式的主要角色如下。

    1. 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
    2. 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
    3. 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
    4. 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

    其结构图如图所示。

    模式的实现

    上图给出建造者(Builder)模式的主要结构,其相关类的代码如下

    (1) 产品角色:包含多个组成部件的复杂对象。

    public class Product {
        private String partA;
        private String partB;
        private String partC;
    
        public void setPartA(String partA) {
            this.partA = partA;
        }
    
        public void setPartB(String partB) {
            this.partB = partB;
        }
    
        public void setPartC(String partC) {
            this.partC = partC;
        }
    
        public void show(){
            // 显示产品的特性内容
        }
    }
    

    (2) 抽象建造者:包含创建产品各个子部件的抽象方法。

    public abstract class Builder {
        // 创建产品对象
        protected Product product = new Product();
        public abstract void buildPartA();
        public abstract void buildPartB();
        public abstract void buildPartC();
        // 返回产品的对象
        public Product getResult(){
            return product;
        }
    }
    

    (3) 具体建造者:实现了抽象建造者接口。

    public class ConcreteBuilder extends Builder{
        @Override
        public void buildPartA() {
            product.setPartA("建造PartA");
        }
    
        @Override
        public void buildPartB() {
            product.setPartB("建造PartB");
        }
    
        @Override
        public void buildPartC() {
            product.setPartC("建造PartC");
        }
    }
    

    (4) 指挥者:调用建造者中的方法完成复杂对象的创建。

    public class Director {
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        // 产品构建与组装工作
        public Product construct(){
            builder.buildPartA();
            builder.buildPartB();
            builder.buildPartC();
            return builder.getResult();
        }
    }
    

    (5) 客户类

    public class Client {
        public static void main(String[] args) {
            Builder builder = new ConcreteBuilder();
            Director director = new Director(builder);
            Product construct = director.construct();
            construct.show();
        }
    }
    

    建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。

    建造者模式主要适用于以下应用场景:

    • 相同的方法,不同的执行顺序,产生不同的结果。
    • 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
    • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
    • 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

    链式赋值

    一个辅导班的课程由教程资料、学习笔记和课后作业组成,但是这些内容的设置顺序可以随意调整,我们用建造者模式来代入理解一下。

    看一下类图的变化,如下图所示:

    首先创建一个课程类 Course。

    public class Course {
        private String name;
        private String means;
        private String notes;
        private String homework;
    	......
        @Override
        public String toString() {
            return "Course{" +
                    "name='" + name + '\'' +
                    ", means='" + means + '\'' +
                    ", notes='" + notes + '\'' +
                    ", homework='" + homework + '\'' +
                    '}';
        }
    }
    

    然后创建建造者类 CourseBuilder,将复杂的过程封装起来,创建步骤由用户决定。

    public class CourseBuilder {
        private Course course = new Course();
        public CourseBuilder addName(String name){
            course.setName(name);
            return this;
        }
    
        public CourseBuilder addMeans(String means){
            course.setMeans(means);
            return this;
        }
    
        public CourseBuilder addNote(String note){
            course.setNotes(note);
            return this;
        }
    
        public CourseBuilder addHomework(String homework){
            course.setHomework(homework);
            return this;
        }
    
        public Course build(){
            return course;
        }
    }
    

    最后编写客户端测试代码。

    public class Main {
        public static void main(String[] args) {
            CourseBuilder builder = new CourseBuilder()
                    .addName("设计模式")
                    .addMeans("教程资料")
                    .addNote("课堂笔记")
                    .addHomework("课后作业");
            System.out.println(builder.build());
        }
    }
    

    输出结果如下:

    Course{name='设计模式', means='教程资料', notes='课堂笔记', homework='课后作业'}

    静态内部类实现

    针对上述的实例,可以将Builder类修改为静态内部类。

    public class Course {
        private String name;
        private String means;
        private String notes;
        private String homework;
        ......
        @Override
        public String toString() {
            return "Course{" +
                    "name='" + name + '\'' +
                    ", means='" + means + '\'' +
                    ", notes='" + notes + '\'' +
                    ", homework='" + homework + '\'' +
                    '}';
        }
    
        public static class Builder{
            private Course course = new Course();
            public Builder addName(String name) {
                course.setName(name);
                return this;
            }
            public Builder addMeans(String means) {
                course.setMeans(means);
                return this;
            }
            public Builder addNote(String note) {
                course.setNotes(note);
                return this;
            }
            public Builder addHomework(String homework) {
                course.setHomework(homework);
                return this;
            }
            public Course build() {
                return course;
            }
        }
    }
    

    客户端测试代码如下:

    public class Main {
        public static void main(String[] args) {
            Course.Builder builder = new Course.Builder()
                    .addName("设计模式")
                    .addMeans("教程资料")
                    .addNote("课堂笔记")
                    .addHomework("课后作业");
            System.out.println(builder.build());
        }
    }
    
  • 相关阅读:
    线段树节点到底开多大
    HDU4901 The Romantic Hero DP
    VIM 配置文件可执行命令
    codeforces159D
    codeforces416B
    codeforces165C
    codeforces332B
    Node.js权威指南 (9)
    iOS-android-windowsphone等移动终端平台开发流程图
    前端面试题细节问题
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14941936.html
Copyright © 2020-2023  润新知