设计模式——建造者模式

发布于:2024-12-21 ⋅ 阅读:(11) ⋅ 点赞:(0)

设计模式——建造者模式

介绍

建造者模式(Builder Pattern)是一种创建型设计模式,它通过将一个复杂对象的构建过程分解成多个简单的步骤,从而使得不同的构建过程可以生成不同的表现形式。建造者模式的关键思想是使用相同的构建步骤来创建不同的对象表示,它适用于构建过程需要多个步骤并且可能有多个不同表现形式的场景。

实现

结构及工作流程

建造者模式的结构

建造者模式通常涉及以下几个角色:

  1. 产品(Product):最终构建出来的复杂对象,通常是由多个部分组成。
  2. 抽象建造者(Builder):声明了构建产品各个部分的抽象方法,通常提供一个 build() 方法来构建完整的对象。
  3. 具体建造者(ConcreteBuilder):实现了抽象建造者中定义的构建方法,完成对各个部件的具体构建工作,最终生成产品。
  4. 指挥者(Director):负责控制建造过程,它使用建造者来构建产品。指挥者与具体建造者进行交互,指定构建的顺序与步骤,最终生成一个完整的产品。
  5. 客户端(Client):客户端通过指挥者来执行建造过程,而不直接与具体建造者打交道。

建造者模式的工作流程

  1. 创建具体建造者:具体建造者实现了产品的具体构建步骤。
  2. 指挥者负责构建过程:指挥者使用具体建造者来按照预定的顺序构建产品。
  3. 客户端获取产品:客户端最终获取由建造者构建完成的产品对象。

经典实现

示例

示例代码:

  1. 产品类

    public class Product {
        private String partA;
        private String partB;
        private String partC;
    
        // Getters and setters
        public String getPartA() {
            return partA;
        }
    
        public void setPartA(String partA) {
            this.partA = partA;
        }
    
        public String getPartB() {
            return partB;
        }
    
        public void setPartB(String partB) {
            this.partB = partB;
        }
    
        public String getPartC() {
            return partC;
        }
    
        public void setPartC(String partC) {
            this.partC = partC;
        }
    
        @Override
        public String toString() {
            return "Product [partA=" + partA + ", partB=" + partB + ", partC=" + partC + "]";
        }
    }
    
  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 is built");
        }
    
        @Override
        public void buildPartB() {
            product.setPartB("PartB is built");
        }
    
        @Override
        public void buildPartC() {
            product.setPartC("PartC is built");
        }
    }
    
  4. 指挥者

    public class Director {
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        // 指挥者控制构建过程
        public void construct() {
            builder.buildPartA();
            builder.buildPartB();
            builder.buildPartC();
        }
    }
    
  5. 测试代码(客户端)

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

以上述为例,在测试代码中,我们只需要将指挥者和具体建造者都创建后,便可轻松获取产品实例。指挥者调控具体建造者,将产品的各个部分进行组装,最终组装出产品对象。
在指挥者的 construct() 方法中,我们也可以将返回值改为具体对象 Product ,这样指挥者调用construct()后,可直接获取产品实例(可能这样做有些画蛇添足了,不过看起来可能会更加快速获取产品实例)

优缺点

优点

  1. 清晰的分工:建造者模式将对象的构建过程分为多个独立的步骤,每个步骤由不同的建造者类负责,使得代码的组织更加清晰。
  2. 复杂对象的构建:可以灵活地处理一些复杂对象的构建,尤其适用于需要多个步骤来创建一个对象的场景。
  3. 可以灵活控制构建过程:由于指挥者类控制了构建的步骤,可以更方便地进行定制和修改构建过程。
  4. 减少代码重复:构建过程中的重复代码被集中到建造者中,客户端不需要直接与构建过程打交道。

缺点

  1. 增加了类的数量:建造者模式需要多个类来完成不同的建造步骤,这会导致类的数量增加,可能会增加系统的复杂度。
  2. 适用于产品变化较小的情况:建造者模式适用于同一个产品的不同表现形式的构建,如果产品的构建方式变化非常大,使用建造者模式可能不太合适。
使用场景

建造者模式适用于以下几种情况:

  1. 构建复杂对象:当构建一个复杂对象时,它通常需要多个部件,而这些部件的构建步骤可以被分离到不同的类中
  2. 构建过程需要多个步骤:如果一个对象的构建过程涉及到多个不同的步骤,但这些步骤之间可以相互独立或顺序执行,那么建造者模式很适合
  3. 需要灵活的产品生成:当同一个产品有多种表现形式,且这些表现形式可能有不同的构建过程时,建造者模式允许灵活控制构建过程

扩展实现

建造者模式除了上面的用途外,在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构。

示例

示例代码:

public class Phone {

    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    private Phone(Builder builder) {
        cpu = builder.cpu;
        screen = builder.screen;
        memory = builder.memory;
        mainboard = builder.mainboard;
    }

    public static final class Builder {
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder() {}

        public Builder cpu(String val) {
            cpu = val;
            return this;
        }
        public Builder screen(String val) {
            screen = val;
            return this;
        }
        public Builder memory(String val) {
            memory = val;
            return this;
        }
        public Builder mainboard(String val) {
            mainboard = val;
            return this;
        }
        public Phone build() {
            return new Phone(this);}
    	}
    
    
    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}

测试代码(客户端)

public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .cpu("intel")
                .mainboard("华硕")
                .memory("金士顿")
                .screen("三星")
                .build();
        System.out.println(phone);
    }
}

通过这种设计,我们可以很轻松的实例化出自己想要的对象。不难发现,这种实例化对象是通过链式编程来实现的,我们在开发时,有时用到的第三方库中,也会有这种实例化对象的方式。对于成员变量过多的类,使用这种方式来获取实例会更加方便些。

总结

建造者模式通过将复杂对象的构建过程分离成多个步骤,使得客户端可以通过不同的建造者来构建出不同的对象。它非常适用于那些构建过程需要多个步骤的复杂对象,能够有效地提高系统的灵活性和可维护性。但它也可能增加类的数量,增加系统的复杂度,因此在选择时需要考虑对象构建的复杂性


网站公告

今日签到

点亮在社区的每一天
去签到