设计模式--建造者模式(bulider)

设计模式--建造者模式(bulider)


建造者模式是什么?

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

建造者模式的特点是什么?

将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的

建造者模式优缺点

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

缺点:内部变化复杂的产品发生变化时,则建造者也要同步修改,后期维护成本较大

建造者的实现方式及其写法

建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者组成

  1. 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
    /**
     * 产品角色(Product)
     * 包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件
     */
    public class Room {
        /**
         * 卫生间
         */
        private String bathroom;
        /**
         * 卧室
         */
        private String livingroom;
        /**
         * 餐厅
         */
        private String dinninghall;
    
        public String getBathroom() {
            return bathroom;
        }
    
        public void setBathroom(String bathroom) {
            this.bathroom = bathroom;
        }
    
        public String getLivingroom() {
            return livingroom;
        }
    
        public void setLivingroom(String livingroom) {
            this.livingroom = livingroom;
        }
    
        public String getDinninghall() {
            return dinninghall;
        }
    
        public void setDinninghall(String dinninghall) {
            this.dinninghall = dinninghall;
        }
    
        @Override
        public String toString() {
            return "Room{" +
                    "bathroom='" + bathroom + '\'' +
                    ", livingroom='" + livingroom + '\'' +
                    ", dinninghall='" + dinninghall + '\'' +
                    '}';
        }
    }

  2. 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 。
    /**
     * 抽象建造者(Builder)可用接口或抽象类
     * 包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法
     */
    public interface RoomBuilder {
        //这几个方法都是由具体建造者去实现
        RoomBuilder bathroom(String br);
        RoomBuilder livingroom(String lr);
        RoomBuilder dinninghall(String dh);
        Room build();
    }

  3. 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
    /**
     * 具体建造者(Concrete Builder)
     * 实现 Builder 接口,完成复杂产品的各个部件的具体创建方法
     */
    public class ConcreteRoomBuilder implements RoomBuilder{
        private Room room= new Room();
        @Override
        public RoomBuilder bathroom(String br) {
            room.setBathroom(br);
            return this;
        }
    
        @Override
        public RoomBuilder livingroom(String lr) {
            room.setLivingroom(lr);
            return this;
        }
    
        @Override
        public RoomBuilder dinninghall(String dh) {
            room.setDinninghall(dh);
            return this;
        }
    
        @Override
        public  Room build() {
            return room;
        }
    }

  4. 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息
    /**
     * 指挥者(Director)
     * 调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息
     */
    public class DesignRoom {
        public static void main(String[] args) {
            ConcreteRoomBuilder concreteRoomBuilder = new ConcreteRoomBuilder();
            Room room = concreteRoomBuilder.bathroom("精装修")
                    .dinninghall("欧式装修")
                    .livingroom("豪华装修")
                    .build();
            System.out.println(room.toString());
        }
    }
    

应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。

最常见的就是Lombok里用到的注解@builder

/**
 * 如果创建的产品种类只有一种,只需要一个具体建造者,
 * 这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色
 */
public class Person {
    int id;
    String name;
    int age;
    double weight;
    int score;
    Location loc;

    private Person() {}

    public static class PersonBuilder {

        Person p = new Person();

        public PersonBuilder basicInfo(int id, String name, int age) {
            p.id = id;
            p.name = name;
            p.age = age;
            return this;
        }

        public PersonBuilder weight(double weight) {
            p.weight = weight;
            return this;
        }

        public PersonBuilder score(int score) {
            p.score = score;
            return this;
        }

        public PersonBuilder loc(String street, String roomNo) {
            p.loc = new Location(street, roomNo);
            return this;
        }

        public Person build() {
            return p;
        }
    }
}

class Location {
    String street;
    String roomNo;

    public Location(String street, String roomNo) {
        this.street = street;
        this.roomNo = roomNo;
    }
}

模式的应用场景

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

当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。

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

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

建造者模式和工厂模式的区别

通过前面的学习,我们已经了解了建造者模式,那么它和工厂模式有什么区别呢?

  • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
  • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
  • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
  • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值