码迷,mamicode.com
首页 > 编程语言 > 详细

07、Java模式--建造者模式

时间:2021-06-28 20:21:39      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:rac   影响   client   pre   多参数   main   赋值   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());
    }
}

07、Java模式--建造者模式

标签:rac   影响   client   pre   多参数   main   赋值   java   相关   

原文地址:https://www.cnblogs.com/pengjingya/p/14941936.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!