设计模式五之建造者模式

  在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
  以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

1. 模式的定义与特点

1.1 模式的定义

  建造者模式的定义(Builder):是指将一个复制的对象与它的表示分离,使同样的构建过程可以创建不同的表示。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以选择的。

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

1.2 模式的特点

  建造者模式的优点有:
    1. 创造类之间相互独立,有利于系统的扩展;
    2. 使用者不必知道产品内部组成的细节。

  建造者模式的缺点有:
    1. 产品的组成部分必须相同,这限制了其使用范围;
    2. 如果产品的内部变化复杂,该模式会增加很多的建造者类。

2. 模式的结构与实现

  建造者模式由产品、抽象建造者、具体建造者和指挥者四个要素组成。

2.1 模式的结构

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

建造者模式类UML

2.2 模式的实现

产品角色

/**
 * 产品角色
 */
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 courseQA) {
        this.courseQA = courseQA;
    }

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

抽象建造者

/**
 * 抽象建造者类,负责创建产品多个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法
 */
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();
}

具体建造者

/**
 * 具体创造者,负责实现 Builder 接口,完成复杂产品各个部件的具体方法
 */
public class ConcreteCourseBuilder extends CourseBuilder {

    private Course course = new Course();

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

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

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

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

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

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

指挥官

/**
 * 指挥官类,负责调用建造者对象中的部件构造与装配方法完成复杂对象的创建
 */
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.buildCoursePPT(coursePPT);
        this.courseBuilder.buildCourseVideo(courseVideo);
        this.courseBuilder.buildCourseArticle(courseArticle);
        this.courseBuilder.buildCourseQA(courseQA);
        return this.courseBuilder.makeCourse();
    }

}

客户端

public class Client {

    public static void main(String[] args) {
        CourseBuilder courseBuilder = new ConcreteCourseBuilder();
        Coach coach = new Coach();
        coach.setCourseBuilder(courseBuilder);
        Course course = coach.makeCourse("Java设计模式",
                "Java设计模式PPT",
                "Java设计模式视频",
                "Java设计模式手记",
                "Java设计模式问答");
        System.out.println(course);
    }

}

  其实,大多数开源软件中,建造者模式可能都不会把四个角色都使用,下面介绍另一个建造者模式的实现模式,使用内部类实现。

public class Course {

    private String courseName;

    private String coursePPT;

    private String courseVideo;

    private String courseArticle;

    private String courseQA;

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

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

    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);
        }
    }
}

客户端

public class Client {

    public static void main(String[] args) {
        Course course = new Course.CourseBuilder()
                .buildCourseName("Java设计模式")
                .buildCoursePPT("Java设计模式PPT")
                .buildCourseVideo("Java设计模式视频")
                .build();
        System.out.println(course);
    }

}

3. 模式在开源软件中的应

3.1 java.lang.StrnigBuffer 类

public final class StringBuffer extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }
    
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }
    
    /**
     * @since 1.8
     */
    @Override
    synchronized StringBuffer append(AbstractStringBuilder asb) {
        toStringCache = null;
        super.append(asb);
        return this;
    }
}

3.2 com.squareup.okhttp.Request 类

public final class Request {
    private final HttpUrl url;
    private final String method;
    private final Headers headers;
    private final RequestBody body;
    private final Object tag;
    private volatile URL javaNetUrl;
    private volatile URI javaNetUri;
    private volatile CacheControl cacheControl;

    private Request(Request.Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.headers = builder.headers.build();
        this.body = builder.body;
        this.tag = builder.tag != null ? builder.tag : this;
    }
    
    public static class Builder {
        private HttpUrl url;
        private String method;
        private com.squareup.okhttp.Headers.Builder headers;
        private RequestBody body;
        private Object tag;
    
        public Builder() {
            this.method = "GET";
            this.headers = new com.squareup.okhttp.Headers.Builder();
        }
    
        private Builder(Request request) {
            this.url = request.url;
            this.method = request.method;
            this.body = request.body;
            this.tag = request.tag;
            this.headers = request.headers.newBuilder();
        }
    
        public Request.Builder url(HttpUrl url) {
            if (url == null) {
                throw new IllegalArgumentException("url == null");
            } else {
                this.url = url;
                return this;
            }
        }
    
        public Request.Builder header(String name, String value) {
            this.headers.set(name, value);
            return this;
        }
    
        public Request.Builder addHeader(String name, String value) {
            this.headers.add(name, value);
            return this;
        }
    
        public Request.Builder removeHeader(String name) {
            this.headers.removeAll(name);
            return this;
        }
    
        public Request.Builder headers(Headers headers) {
            this.headers = headers.newBuilder();
            return this;
        }
    
        public Request.Builder cacheControl(CacheControl cacheControl) {
            String value = cacheControl.toString();
            return value.isEmpty() ? this.removeHeader("Cache-Control") : this.header("Cache-Control", value);
        }
    
        public Request build() {
            if (this.url == null) {
                throw new IllegalStateException("url == null");
            } else {
                return new Request(this);
            }
        }
    }
} 

客户端

private static String post(String url, String json, String content, String surity) throws IOException {
    RequestBody body = RequestBody.create(JSON, json);
    Request request = new Request.Builder()
            .url(url)
            .post(body)
            .addHeader("Content-MD5", content)
            .addHeader("Content-Security", surity)
            .build();
    Response response = client.newCall(request).execute();
    if (response.isSuccessful()) {
        return new String(response.body().string().getBytes("UTF8"));
    } else {
        throw new IOException("Unexpected code " + response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值